diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..604544c --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# API Key to communicate with IPFS gateways +IPFS_API_KEY=your_api_key \ No newline at end of file diff --git a/.gitignore b/.gitignore index 05b5b9e..316d7dd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,14 +6,27 @@ artifacts .deps lit_config*env wallets +alias_node_configs node_configs .DS_Store +deployments +deployed*contracts-temp.json +scripts/deployConfig/configs/* +scripts/generate_wallet_and_add_as_alias_manifest.json # IDEs *.iml .idea *.gz *.core +yarn-error.log +npm-*.log +typechain-types -# Linked contracts -contracts/ContractResolver.sol +anvil.log + +.env* +!.env*.example +networkContext.json + +abis/*.json \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..dfc3f9f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +artifacts +cache +wallets +.prettierrc* +*.json +*.yaml +typechain-types \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 3b1b69a..6d3d3b2 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,10 +1,23 @@ { + "arrowParens": "always", + "bracketSpacing": true, + "endOfLine": "lf", + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "singleAttributePerLine": false, + "bracketSameLine": false, + "jsxBracketSameLine": false, + "jsxSingleQuote": false, "printWidth": 80, - "tabWidth": 4, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", "useTabs": false, - "singleQuote": false, - "bracketSpacing": true, - "explicitTypes": "always", + "vueIndentScriptAndStyle": false, "overrides": [ { "files": "*.sol", @@ -14,8 +27,16 @@ "useTabs": false, "singleQuote": false, "bracketSpacing": true, - "explicitTypes": "always" + "parser": "solidity-parse" + } + }, { + "files": "*.md", + "options": { + "tabWidth": 2, + "parser": "markdown" } } - ] + ], + "parser": "babel-ts" } + \ No newline at end of file diff --git a/Makefile b/Makefile index f4bce38..b3bcbfa 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ -setup: - @@./deployInit.sh _SETUP_ - +run-test: + pkill -9 anvil || true + anvil -a 10 > anvil.log 2>&1 & + npm run test:ci \ No newline at end of file diff --git a/README.md b/README.md index a31b820..22319a4 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,15 @@ Learn more here: https://developer.litprotocol.com/docs/litactionsandpkps/whatar # TODO -- Tests for the token reward in the staking contracts (Staking.sol and Staking.js) -- Make it so that the nodes can't accidently kick eachother to below the threshold. Limit the number of nodes that can be kicked per epoch? Have the ability to rejoin if kicked and recovered? +- Tests for the token reward in the staking contracts (Staking.sol and Staking.js) +- Make it so that the nodes can't accidently kick eachother to below the threshold. Limit the number of nodes that can be kicked per epoch? Have the ability to rejoin if kicked and recovered? + +# Running Tests + +In order to run the contract tests, you will need to follow these instrucitons: + +1. Start an instance of our forked Anvil locally. The forked Anvil contains a precompile for the key derivation function and can be found here: https://github.com/LIT-Protocol/foundry +2. Run `npm run test` # How to verify contracts @@ -18,28 +25,132 @@ The second param is any constructor params. # Deploying -Prepare (you only need to run this once): - -```shell -make setup -``` - -Then to perform the deploy: - -```shell -./deployEverything.sh [resolver_address] [chain] +1. Run `npm install` to install project dependencies. +2. Run `npm run test` to test the smart contracts. +3. Export the private key to the environment depending on your deployment target - refer to `hardhat.config.ts` for more details. For example, if deploying to Polygon Mumbia, export `LIT_MUMBAI_DEPLOYER_PRIVATE_KEY=`. If deploying to LIT Rollup (Chronicle), export `LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY=`. +4. Export the API key for IPFS to the environment variable `IPFS_API_KEY`. You can also declare it inside a `.env` - refer to the `.env.example`. +5. `npm run deploy -- --network ` + +- If you know exactly which deployment full config file you would like to use, you can do `npm run deploy -- --deploy-config `. The `--network` option is not needed here as the deploy config file contains that parameter. + +**Note**: The wallet you provide should have at least 10 LIT for the gas to complete the entire deployment process which includes funding & staking the nodes which is called internally in the deploy script. If you don't have that much LIT you may ask Chris on Slack for it. You could also get some from the Chronicle Faucet but it only gives out a tiny amount so you would have to modify the deploy scripts to fund each of the node wallets with less tokens. + +- [Chronicle Faucet](https://faucet.litprotocol.com/) + +**Note**: The deploy script will set the ownership of each contract to the `newOwner` address defined in scripts/deploy_lit_node_contracts.js. If you need to call owner / admin functions on the contracts after they're deployed, you can set that `newOwner` address to something you control. If you're just using the contracts with the nodes you probably don't need to do this. + +Once this script is done running, if you answered "y" to "Should we copy the node config files into the node folder", there will be config files for you generated in /node_configs of this repo. You can copy these to the /config folder of the lit_node_rust repo. + +## Local Deployment + +These are the instructions for deploying + the smart contracts locally: + +1. Run a local blockchain / testnet using [Hardhat](https://hardhat.org/hardhat-network/docs/overview#running-stand-alone-in-order-to-support-wallets-and-other-software), [Anvil](https://book.getfoundry.sh/anvil/) or other software. It must be listening on port `8545` on `localhost`. +2. `npm run deploy -- --network localchain` and follow the interactive prompts. +3. Select `dev` for the environment. +4. Specify a wallet address that you own / have access to when specifying the `newOwnerAddress`. +5. Accept to copy the node configs to the Rust project. +6. Choose anywhere from 3 to 10 for the number of node wallets. +7. Use the default IP addresses as suggested. + +Here is an example deployment configuration: + +```json +{ + "deploymentSelection": "lit-core + lit-node", + "deployNodeConfig": { + "environment": "dev", + "networkName": "localchain", + "newOwnerAddress": "0x4259E44670053491E7b4FE4A120C70be1eAD646b", + "numberOfStakedOnlyWallets": 3, + "resolverContractAddress": "TBD", + "useLitCoreDeploymentResolverContractAddress": true, + "outputTempFilePath": "./deployed-lit-node-contracts-temp.json", + "copyNodeConfigsToRustProject": true, + "ipAddresses": ["127.0.0.1:7470", "127.0.0.1:7471", "127.0.0.1:7472"] + }, + "deployCoreConfig": { + "environment": "dev", + "networkName": "localchain", + "subnetOwnerAddress": "0xB77AEBbC262Bb809933D991A919A0e4A6A3b2f65", + "subnetAdminPublicKey": "0x045f96e860435fccf287d9c2592fa129edfca7159c8dd2260cf2def38a9d5ee627ba73afef636467bc95fe551f10c862e910f18eafb751226d6901eab7d5b2794a", + "subnetProvAddress": "0x3324439C8b9181eF07D54030E32d2CD22FF0C6A7", + "outputTempFilePath": "./deployed-lit-core-contracts-temp.json" + } +} ``` -- **env**: Environment (dev, test or prod). -- **resolver_address**: Address of the ContractResolver (optional). -- **chain**: Chain (optional, defaults to mumbai). - -Use the `deployEverything.sh` script to deploy all the contracts and create config files for the nodes. You should set the ENV var LIT_MUMBAI_DEPLOYER_PRIVATE_KEY to the private key of the account you want to deploy from. It should have Polygon Mumbai testnet tokens in it for gas. You can get them from the [Polygon Mumbai faucet](https://faucet.matic.network/) or from the [Alchemy mumbai faucet](https://mumbaifaucet.com/) or if you need even more ask Chris on slack. - -Note: The deploy script will set the ownership of each contract to the `newOwner` address defined in scripts/deploy_everything.js. If you need to call owner / admin functions on the contracts after they're deployed, you can set that `newOwner` address to something you control. If you're just using the contracts with the nodes you probably don't need to do this. - -Once this script is done running, there will be config files for you generated in /node_configs of this repo. You can copy these to the /config folder of the lit_node_rust repo. - -# ContractResolver.sol - -This file lives in the lit-os repo. Run "make setup" to pull it in here. If you need to edit it, edit it in the lit-os repo. +# Contract Deployment Tooling + +We have developed a tool that makes it convenient to deploy and configure our suite of smart contracts before spinning up a network of nodes against them. Specifically, our tool helps with: + +- Deploying Lit Core and/or Lit Node smart contracts to any supported chain +- After deploying smart contracts, configure the smart contract parameters and settings per each of the node operators + +## Technical Details + +- The tool is available as a `npm` script - `npm run deploy -- --network ` + - The currently supported network names are: + - `celo` + - `mumbai` + - `alfajores` + - `polygon` + - `litTestnet` + - `lit` + - `localchain` +- At a high-level, the tool consists of 2 main steps: + 1. An **interactive** step that determines the entire set of deployment configurations that will be used. + 2. A **non-interactive** step that takes a deployment configuration and deploys and configures a set of smart contracts accodingly. +- Running the entire tool as it is will involve an interactive experience (eg. command-line experience). If you wish to have a non-interactive experience, that is only available by running the tool and specifying exactly which deployment configuration you would like to use, ie. `npm run deploy -- --deploy-config `. The `--network` option is not needed here as the deploy config file contains that parameter. +- The non-interactive deployment step is run as a child process that is spawned. All environment variables are inherited in the spawned environment. We pass in additional environment variables. +- When running the interactive first step, + - you will have the option to choose whether to deploy: + 1. Only the Lit Core contracts + 2. Only the Lit Node contracts + 3. Both the Lit Core and Lit Node contracts, and in that order. + - you will have the option to choose a previously generated deployment configuration. + - **This is the true power of this tool, in allowing you to reference EXACTLY a deployment configuration that has worked well for your needs previously**. +- This tool is environment-aware and will ask for confirmation before proceeding to use parameters specified in your shell session. Refer to the Deployment Configuration Reference section below for more details. +- This tool uses [`inquirer.js`](https://github.com/SBoudrias/Inquirer.js) to create the interactive experience. + +## Deployment Configuration + +The deployment configuration refers to the entire set of parameters that will be used for deploying and configuring the smart contracts. + +### Persistence + +- Each deployment configuration is persisted to disk locally under the `scripts/deployConfig/configs` directory. +- In order for a persisted deployment configuration to be detected by the tool, it must match the following pattern `deploy-config-*.json` + +### Reference + +Here is an explanation for each of the fields in the deployment configuration: + +| Key Path | Type | Description | +| -------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `deploymentSelection` | `string` | An enum of either `lit-core`, `lit-core + lit-node` or `lit-node` describing which set of smart contracts should be deployed. | +| `deployNodeConfig` | `object` | The deployment configuration parameters that relate to deploying the Lit Node smart contracts. | +| `deployNodeConfig.environment` | `string` | An enum of either `dev`, `staging` or `prod` describing which deployment environment the Lit Node contracts should be deployed to. | +| `deployNodeConfig.networkName` | `string` | The name of the network (chain) the Lit Node contracts should be deployed to. | +| `deployNodeConfig.newOwnerAddress` | `string` | The EVM-compatible address that will be given ownership and configuration permissions once the tool finishes. While the tool uses the deployer address to configure the smart contract parameters after deployment, you would most likely want to revoke admin / owner permissions from the deployer and grant your own address such permissions after the tool finishes. If `LIT_OWNER_WALLET_ID` is set in your environment, the tool will ask for confirmation before using this parameter. | +| `deployNodeConfig.numberOfStakedOnlyWallets` | `number` | The number of nodes (and node operators) that only stake on the network. | +| `deployNodeConfig.numberOfStakedAndJoinedWallets` | `number` | The number of nodes (and node operators) that stake and request to join the network. If a node is already accounted for in `deployNodeConfig.numberOfStakedOnlyWallets`, do not account for that node here, as the total number of stakers will be the sum of the two. The nodes that are joining will be the first `numberOfStakedAndJoinedWallets` entries from the overall node wallets list that is generated. | +| `deployNodeConfig.resolverContractAddress` | `string` | The Lit Core `ContractResolver` contract address that will be referenced. It will be marked as `TBD` when `deployNodeConfig.useLitCoreDeploymentResolverContractAddress` is set to `true`, since we won't know the smart contract address until the non-interactive deployment step of the tool. If `LIT_RESOLVER_CONTRACT_ADDRESS` is set in your environment, the tool will ask for confirmation before using this parameter. | +| `deployNodeConfig.useLitCoreDeploymentResolverContractAddress` | `boolean` | Whether to use the `ContractResolver` contract address from deploying the Lit Core contracts. | +| `deployNodeConfig.outputTempFilePath` | `string` | The path to the file containing the addresses of the deployed Lit Node smart contracts. | +| `deployNodeConfig.copyNodeConfigsToRustProject` | `boolean` | Whether to copy the generated node configs over to the Rust project. You will likely need this when spinning up a network locally on your machine. | +| `deployNodeConfig.ipAddresses` | `string[]` | An array of strings representing the IP addresses of the node operators. You will likely need this when spinning up a network locally on your machine. If `IP_ADDRESSES` is set in your environment, the tool will ask for confirmation before using this parameter. | +| `deployNodeConfig.existingRouterAndPkpContracts` | `object` | An object containing the addresses of smart contracts from a prior deployment to be referenced again in this current deployment. | +| `deployCoreConfig` | `object` | The deployment configuration parameters that relate to deploying the Lit Core smart contracts. | +| `deployCoreConfig.environment` | `string` | An enum of either `dev`, `staging` or `prod` describing which deployment environment the Lit Core contracts should be deployed to. | +| `deployCoreConfig.networkName` | `string` | The name of the network (chain) the Lit Core contracts should be deployed to. | +| `deployCoreConfig.subnetOwnerAddress` | `string` | The address of the subnet owner. | +| `deployCoreConfig.subnetAdminPublicKey` | `string` | The public key of the subnet admin. | +| `deployCoreConfig.subnetProvAddress` | `string` | The address of the wallet that provisions the subnet. | +| `deployCoreConfig.outputTempFilePath` | `string` | The path to the file containing the addresses of the deployed Lit Core smart contracts. | +| `deploySensitiveConfig` | `string` | The deployment configuration parameters that are sensitive. These parameters are never stored to disk and are only provided via the environment. | +| `deploySensitiveConfig.ipfsApiKey` | `string` | The IPFS API key | + +# Deployed Contract Addresses + +Deployed contract addresses are listed by network in this repo: https://github.com/LIT-Protocol/networks diff --git a/abis/Allowlist.abi b/abis/Allowlist.abi new file mode 100644 index 0000000..91af089 --- /dev/null +++ b/abis/Allowlist.abi @@ -0,0 +1,227 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "ItemAllowed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "ItemNotAllowed", + "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": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "addAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allowAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "allowedItems", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "isAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "removeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_allowAll", + "type": "bool" + } + ], + "name": "setAllowAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "setAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "setNotAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/BackupRecovery.abi b/abis/BackupRecovery.abi new file mode 100644 index 0000000..5eb9152 --- /dev/null +++ b/abis/BackupRecovery.abi @@ -0,0 +1,1115 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "senderPublicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "blsKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "senderBlsKey", + "type": "bytes" + } + ], + "name": "BackupKeysMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "peer", + "type": "address" + } + ], + "name": "BackupMemberNotMappedToNode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "members", + "type": "address[]" + } + ], + "name": "BackupSetIncomplete", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "BackupStateAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "BackupStateNotRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "InvalidCaller", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "NodesAllMappedToBackupMembers", + "type": "error" + }, + { + "inputs": [], + "name": "ProofExpired", + "type": "error" + }, + { + "inputs": [], + "name": "WrongVerificationVersion", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sessionId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "bls12381G1EncKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "secp256K1EcdsaPubKey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "partyThreshold", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + } + ], + "indexed": false, + "internalType": "struct LibBackupRecoveryStorage.BackupRecoveryState", + "name": "state", + "type": "tuple" + } + ], + "name": "BackupKeysRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "partyTheshold", + "type": "uint256" + } + ], + "name": "BackupPartyRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ContractResolverAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "backupMemberAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "NodeAddress", + "type": "address" + } + ], + "name": "NodeAssignedToBackupMember", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LibBackupRecoveryStorage.RecoveryKey", + "name": "recoveryKey", + "type": "tuple" + } + ], + "name": "RecoveryKeySet", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_EC_OP_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_calculatePartyThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "_checkValidatorSetForAddress", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_getStakingViewFacet", + "outputs": [ + { + "internalType": "contract StakingViewsFacet", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allBackupMembersMapped", + "outputs": [ + { + "internalType": "bool", + "name": "mapped", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBackupPartyState", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sessionId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "bls12381G1EncKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "secp256K1EcdsaPubKey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "partyThreshold", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + } + ], + "internalType": "struct LibBackupRecoveryStorage.BackupRecoveryState", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDecryptionThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMemberForNodeDkg", + "outputs": [ + { + "internalType": "address", + "name": "bp", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextBackupPartyMembers", + "outputs": [ + { + "internalType": "address[]", + "name": "backupMembers", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextBackupState", + "outputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct LibBackupRecoveryStorage.RecoveryKey[]", + "name": "registeredRecoveryKeys", + "type": "tuple[]" + } + ], + "internalType": "struct LibBackupRecoveryStorage.NextStateDownloadable", + "name": "nextState", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNodeAddressesForDkg", + "outputs": [ + { + "internalType": "address[]", + "name": "nodes", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNodeForBackupMember", + "outputs": [ + { + "internalType": "address", + "name": "peer", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "sessionId", + "type": "bytes" + } + ], + "name": "getPastBackupState", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sessionId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "bls12381G1EncKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "secp256K1EcdsaPubKey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "partyThreshold", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + } + ], + "internalType": "struct LibBackupRecoveryStorage.BackupRecoveryState", + "name": "partyState", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProofSubmissionForBackupPartyMember", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakerAddressesForDkg", + "outputs": [ + { + "internalType": "address[]", + "name": "nodes", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isNodeForDkg", + "outputs": [ + { + "internalType": "bool", + "name": "inSet", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isRecoveryDkgCompleted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "encryptedKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "sessionId", + "type": "bytes" + } + ], + "name": "recieveNewKeySet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + } + ], + "name": "recieveProofBls12381G1", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + } + ], + "name": "recieveProofsK256", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + } + ], + "name": "registerNewBackupParty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct LibBackupRecoveryStorage.RecoveryKey[]", + "name": "recoveryKeys", + "type": "tuple[]" + } + ], + "name": "registerRecoveryKeys", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setMemberForDkg", + "outputs": [ + { + "internalType": "address", + "name": "bp", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clearNodeRecoveryStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNodeRecoveryStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "node_address", + "type": "address" + }, + { + "internalType": "enum LibBackupRecoveryStorage.NodeRecoveryStatus", + "name": "status", + "type": "uint8" + } + ], + "internalType": "struct LibBackupRecoveryStorage.NodeRecoveryStatusMap[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum LibBackupRecoveryStorage.NodeRecoveryStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "setNodeRecoveryStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "bls12381G1EncKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "secp256K1EcdsaPubKey", + "type": "bytes" + }, + { + "internalType": "address[]", + "name": "partyMembers", + "type": "address[]" + } + ], + "name": "setBackupPartyState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonSubmitingBackupMembersInNextState", + "outputs": [ + { + "internalType": "address[]", + "name": "missingRecoveryMembers", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/ContractResolver.abi b/abis/ContractResolver.abi new file mode 100644 index 0000000..5368f68 --- /dev/null +++ b/abis/ContractResolver.abi @@ -0,0 +1,630 @@ +[ + { + "inputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AdminRoleRequired", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "AllowedEnvAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "AllowedEnvRemoved", + "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": "bytes32", + "name": "typ", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetContract", + "type": "event" + }, + { + "inputs": [], + "name": "ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ALLOWLIST_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BACKUP_RECOVERY_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_WALLET_REGISTRY", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "HD_KEY_DERIVER_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIT_TOKEN_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTI_SENDER_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAYMENT_DELEGATION_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PKP_HELPER_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PKP_HELPER_V2_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PKP_NFT_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PKP_NFT_METADATA_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PKP_PERMISSIONS_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PUB_KEY_ROUTER_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_LIMIT_NFT_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELEASE_REGISTER_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_BALANCES_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_CONTRACT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "addAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "addAllowedEnv", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "typ", + "type": "bytes32" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "getContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adminBeingRemoved", + "type": "address" + } + ], + "name": "removeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "removeAllowedEnv", + "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": "bytes32", + "name": "typ", + "type": "bytes32" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "env", + "type": "uint8" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "setContract", + "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": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "", + "type": "uint8" + } + ], + "name": "typeAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/DevKeyDeriver.abi b/abis/DevKeyDeriver.abi new file mode 100644 index 0000000..5d9ee47 --- /dev/null +++ b/abis/DevKeyDeriver.abi @@ -0,0 +1,53 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct IPubkeyRouter.RootKey[]", + "name": "rootHDKeys", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "name": "computeHDPubKey", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/DomainWalletOracle.abi b/abis/DomainWalletOracle.abi new file mode 100644 index 0000000..a66e9fb --- /dev/null +++ b/abis/DomainWalletOracle.abi @@ -0,0 +1,730 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_contractResolver", + "type": "address" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "_env", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "DomainAlreadyRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registryAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NonRegistryCaller", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + } + ], + "name": "Expired", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Registered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + } + ], + "name": "Removed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + } + ], + "name": "Revoked", + "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" + }, + { + "inputs": [], + "name": "ADMIN_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": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "addAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + } + ], + "name": "checkRegistration", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "contractResolver", + "outputs": [ + { + "internalType": "contract ContractResolver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "env", + "outputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getDomainIdByTokenId", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + } + ], + "name": "getDomainTokenIdByUri", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getDomainUri", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getExpiration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + } + ], + "name": "getPkpTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getRecord", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "hasExpired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "hasOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "isRouted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "userId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + } + ], + "name": "registerDomain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "registerPKP", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adminBeingRemoved", + "type": "address" + } + ], + "name": "removeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "removeDomain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "revokeDomain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "record", + "type": "bytes" + } + ], + "name": "updateDomainRecord", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/DomainWalletRegistry.abi b/abis/DomainWalletRegistry.abi new file mode 100644 index 0000000..50f240a --- /dev/null +++ b/abis/DomainWalletRegistry.abi @@ -0,0 +1,979 @@ +[ + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "metadataCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validMetadataCount", + "type": "uint256" + } + ], + "name": "InvalidNftMetadataCollectionLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + } + ], + "name": "MaximumCharacterLimitExceeded", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + } + ], + "name": "Expired", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Registered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + } + ], + "name": "Removed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "subDomain", + "type": "bytes" + } + ], + "name": "Revoked", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "hasExpired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "userId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + }, + { + "internalType": "string[]", + "name": "nftMetadata", + "type": "string[]" + } + ], + "name": "registerDomain", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "userId", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "string[]", + "name": "nftMetadata", + "type": "string[]" + } + ], + "name": "registerDomainAndMintNext", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "registerPKP", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "removeDomain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "revokeDomain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + }, + { + "internalType": "string[]", + "name": "nftMetadata", + "type": "string[]" + } + ], + "name": "setPKPMetadata", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "record", + "type": "bytes" + } + ], + "name": "updateDomainRecord", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "DomainAlreadyRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + } + ], + "name": "checkRegistration", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainCharacterLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getDomainIdByTokenId", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "uri", + "type": "bytes" + } + ], + "name": "getDomainTokenIdByUri", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getDomainUri", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainWalletRegistryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getExpiration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpHelperAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + } + ], + "name": "getPkpTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "getRecord", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "hasOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pkpTokenId", + "type": "uint256" + } + ], + "name": "isRouted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/IKeyDeriver.abi b/abis/IKeyDeriver.abi new file mode 100644 index 0000000..7911fbc --- /dev/null +++ b/abis/IKeyDeriver.abi @@ -0,0 +1,48 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct IPubkeyRouter.RootKey[]", + "name": "rootHDKeys", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "name": "computeHDPubKey", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/KeyDeriver.abi b/abis/KeyDeriver.abi new file mode 100644 index 0000000..c87d7ce --- /dev/null +++ b/abis/KeyDeriver.abi @@ -0,0 +1,66 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "HD_KDF", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct IPubkeyRouter.RootKey[]", + "name": "rootHDKeys", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "name": "computeHDPubKey", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/LITToken.abi b/abis/LITToken.abi new file mode 100644 index 0000000..ce23d8b --- /dev/null +++ b/abis/LITToken.abi @@ -0,0 +1,1044 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "cap", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidShortString", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "str", + "type": "string" + } + ], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "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": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CLOCK_MODE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "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": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "votes", + "type": "uint224" + } + ], + "internalType": "struct ERC20Votes.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clock", + "outputs": [ + { + "internalType": "uint48", + "name": "", + "type": "uint48" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "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": [ + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timepoint", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "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": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "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", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "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": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/Multisender.abi b/abis/Multisender.abi new file mode 100644 index 0000000..7687846 --- /dev/null +++ b/abis/Multisender.abi @@ -0,0 +1,105 @@ +[ + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_recipients", + "type": "address[]" + } + ], + "name": "sendEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_recipients", + "type": "address[]" + }, + { + "internalType": "address", + "name": "tokenContract", + "type": "address" + } + ], + "name": "sendTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenContract", + "type": "address" + } + ], + "name": "withdrawTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/PKPHelper.abi b/abis/PKPHelper.abi new file mode 100644 index 0000000..a87a565 --- /dev/null +++ b/abis/PKPHelper.abi @@ -0,0 +1,845 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_resolver", + "type": "address" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "_env", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ContractResolverAddressSet", + "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": "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": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + } + ], + "internalType": "struct IPubkeyRouter.Signature[]", + "name": "signatures", + "type": "tuple[]" + } + ], + "internalType": "struct LibPKPNFTStorage.ClaimMaterial", + "name": "claimMaterial", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "permittedIpfsCIDs", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedIpfsCIDScopes", + "type": "uint256[][]" + }, + { + "internalType": "address[]", + "name": "permittedAddresses", + "type": "address[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAddressScopes", + "type": "uint256[][]" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "bool", + "name": "addPkpEthAddressAsPermittedAddress", + "type": "bool" + }, + { + "internalType": "bool", + "name": "sendPkpToItself", + "type": "bool" + } + ], + "internalType": "struct PKPHelper.AuthMethodData", + "name": "authMethodData", + "type": "tuple" + } + ], + "name": "claimAndMintNextAndAddAuthMethods", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + } + ], + "internalType": "struct IPubkeyRouter.Signature[]", + "name": "signatures", + "type": "tuple[]" + } + ], + "internalType": "struct LibPKPNFTStorage.ClaimMaterial", + "name": "claimMaterial", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "permittedIpfsCIDs", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedIpfsCIDScopes", + "type": "uint256[][]" + }, + { + "internalType": "address[]", + "name": "permittedAddresses", + "type": "address[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAddressScopes", + "type": "uint256[][]" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "bool", + "name": "addPkpEthAddressAsPermittedAddress", + "type": "bool" + }, + { + "internalType": "bool", + "name": "sendPkpToItself", + "type": "bool" + } + ], + "internalType": "struct PKPHelper.AuthMethodData", + "name": "authMethodData", + "type": "tuple" + } + ], + "name": "claimAndMintNextAndAddAuthMethodsWithTypes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "contractResolver", + "outputs": [ + { + "internalType": "contract ContractResolver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "env", + "outputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainWalletRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPKPNftMetdataAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpNftAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpPermissionsAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "bool", + "name": "addPkpEthAddressAsPermittedAddress", + "type": "bool" + }, + { + "internalType": "bool", + "name": "sendPkpToItself", + "type": "bool" + } + ], + "name": "mintNextAndAddAuthMethods", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "permittedIpfsCIDs", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedIpfsCIDScopes", + "type": "uint256[][]" + }, + { + "internalType": "address[]", + "name": "permittedAddresses", + "type": "address[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAddressScopes", + "type": "uint256[][]" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "bool", + "name": "addPkpEthAddressAsPermittedAddress", + "type": "bool" + }, + { + "internalType": "bool", + "name": "sendPkpToItself", + "type": "bool" + } + ], + "name": "mintNextAndAddAuthMethodsWithTypes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypes", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIds", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeys", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopes", + "type": "uint256[][]" + }, + { + "internalType": "string[]", + "name": "nftMetadata", + "type": "string[]" + }, + { + "internalType": "bool", + "name": "addPkpEthAddressAsPermittedAddress", + "type": "bool" + }, + { + "internalType": "bool", + "name": "sendPkpToItself", + "type": "bool" + } + ], + "name": "mintNextAndAddDomainWalletMetadata", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "removePkpMetadata", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "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": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string[]", + "name": "nftMetadata", + "type": "string[]" + } + ], + "name": "setPkpMetadata", + "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": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/PKPNFT.abi b/abis/PKPNFT.abi new file mode 100644 index 0000000..f8b789c --- /dev/null +++ b/abis/PKPNFT.abi @@ -0,0 +1,1190 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "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": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ContractResolverAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newFreeMintSigner", + "type": "address" + } + ], + "name": "FreeMintSignerSet", + "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": "newMintCost", + "type": "uint256" + } + ], + "name": "MintCostSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "PKPMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrew", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + } + ], + "internalType": "struct IPubkeyRouter.Signature[]", + "name": "signatures", + "type": "tuple[]" + } + ], + "name": "claimAndMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "freeMintSigner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getEthAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextDerivedKeyId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpNftMetadataAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpPermissionsAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRouterAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "ipfsCID", + "type": "bytes" + } + ], + "name": "mintGrantAndBurnNext", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "name": "mintNext", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "prefixed", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "redeemedFreeMintIds", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "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": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newFreeMintSigner", + "type": "address" + } + ], + "name": "setFreeMintSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMintCost", + "type": "uint256" + } + ], + "name": "setMintCost", + "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": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/PKPNFTMetadata.abi b/abis/PKPNFTMetadata.abi new file mode 100644 index 0000000..0592fd9 --- /dev/null +++ b/abis/PKPNFTMetadata.abi @@ -0,0 +1,154 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_resolver", + "type": "address" + }, + { + "internalType": "enum ContractResolver.Env", + "name": "_env", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "buffer", + "type": "bytes" + } + ], + "name": "bytesToHex", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "contractResolver", + "outputs": [ + { + "internalType": "contract ContractResolver", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "env", + "outputs": [ + { + "internalType": "enum ContractResolver.Env", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "removeProfileForPkp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "removeUrlForPKP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "imgUrl", + "type": "string" + } + ], + "name": "setProfileForPKP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "url", + "type": "string" + } + ], + "name": "setUrlForPKP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + }, + { + "internalType": "address", + "name": "ethAddress", + "type": "address" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/PKPPermissions.abi b/abis/PKPPermissions.abi new file mode 100644 index 0000000..deecd0a --- /dev/null +++ b/abis/PKPPermissions.abi @@ -0,0 +1,1262 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ContractResolverAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "userPubkey", + "type": "bytes" + } + ], + "name": "PermittedAuthMethodAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "PermittedAuthMethodRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "scopeId", + "type": "uint256" + } + ], + "name": "PermittedAuthMethodScopeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "scopeId", + "type": "uint256" + } + ], + "name": "PermittedAuthMethodScopeRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "group", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "root", + "type": "bytes32" + } + ], + "name": "RootHashUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "ipfsCID", + "type": "bytes" + }, + { + "internalType": "uint256[]", + "name": "scopes", + "type": "uint256[]" + } + ], + "name": "addPermittedAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "scopes", + "type": "uint256[]" + } + ], + "name": "addPermittedAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "userPubkey", + "type": "bytes" + } + ], + "internalType": "struct LibPKPPermissionsStorage.AuthMethod", + "name": "authMethod", + "type": "tuple" + }, + { + "internalType": "uint256[]", + "name": "scopes", + "type": "uint256[]" + } + ], + "name": "addPermittedAuthMethod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "scopeId", + "type": "uint256" + } + ], + "name": "addPermittedAuthMethodScope", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypesToAdd", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIdsToAdd", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodPubkeysToAdd", + "type": "bytes[]" + }, + { + "internalType": "uint256[][]", + "name": "permittedAuthMethodScopesToAdd", + "type": "uint256[][]" + }, + { + "internalType": "uint256[]", + "name": "permittedAuthMethodTypesToRemove", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "permittedAuthMethodIdsToRemove", + "type": "bytes[]" + } + ], + "name": "batchAddRemoveAuthMethods", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "getAuthMethodId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getEthAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPermittedActions", + "outputs": [ + { + "internalType": "bytes[]", + "name": "", + "type": "bytes[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPermittedAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "maxScopeId", + "type": "uint256" + } + ], + "name": "getPermittedAuthMethodScopes", + "outputs": [ + { + "internalType": "bool[]", + "name": "", + "type": "bool[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPermittedAuthMethods", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "userPubkey", + "type": "bytes" + } + ], + "internalType": "struct LibPKPPermissionsStorage.AuthMethod[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpNftAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRouterAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "getTokenIdsForAuthMethod", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "getUserPubkeyForAuthMethod", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "ipfsCID", + "type": "bytes" + } + ], + "name": "isPermittedAction", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "isPermittedAddress", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "isPermittedAuthMethod", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "scopeId", + "type": "uint256" + } + ], + "name": "isPermittedAuthMethodScopePresent", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "ipfsCID", + "type": "bytes" + } + ], + "name": "removePermittedAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "removePermittedAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + } + ], + "name": "removePermittedAuthMethod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "authMethodType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "scopeId", + "type": "uint256" + } + ], + "name": "removePermittedAuthMethodScope", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "group", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "root", + "type": "bytes32" + } + ], + "name": "setRootHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "group", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + }, + { + "internalType": "bytes32", + "name": "leaf", + "type": "bytes32" + } + ], + "name": "verifyState", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "group", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + }, + { + "internalType": "bool[]", + "name": "proofFlags", + "type": "bool[]" + }, + { + "internalType": "bytes32[]", + "name": "leaves", + "type": "bytes32[]" + } + ], + "name": "verifyStates", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/PaymentDelegation.abi b/abis/PaymentDelegation.abi new file mode 100644 index 0000000..6aa317e --- /dev/null +++ b/abis/PaymentDelegation.abi @@ -0,0 +1,606 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "requestsPerPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LibPaymentDelegationStorage.Restriction", + "name": "restriction", + "type": "tuple" + } + ], + "name": "RestrictionSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "delegatePayments", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "users", + "type": "address[]" + } + ], + "name": "delegatePaymentsBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getPayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "users", + "type": "address[]" + } + ], + "name": "getPayersAndRestrictions", + "outputs": [ + { + "internalType": "address[][]", + "name": "", + "type": "address[][]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "requestsPerPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "internalType": "struct LibPaymentDelegationStorage.Restriction[][]", + "name": "", + "type": "tuple[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payer", + "type": "address" + } + ], + "name": "getRestriction", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "requestsPerPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "internalType": "struct LibPaymentDelegationStorage.Restriction", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payer", + "type": "address" + } + ], + "name": "getUsers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "requestsPerPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "internalType": "struct LibPaymentDelegationStorage.Restriction", + "name": "r", + "type": "tuple" + } + ], + "name": "setRestriction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "undelegatePayments", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "users", + "type": "address[]" + } + ], + "name": "undelegatePaymentsBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/PubkeyRouter.abi b/abis/PubkeyRouter.abi new file mode 100644 index 0000000..de8c858 --- /dev/null +++ b/abis/PubkeyRouter.abi @@ -0,0 +1,882 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ContractResolverAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "PubkeyRoutingDataSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct IPubkeyRouter.RootKey", + "name": "rootKey", + "type": "tuple" + } + ], + "name": "RootKeySet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + } + ], + "name": "adminResetRootKeys", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + } + ], + "internalType": "struct IPubkeyRouter.Signature[]", + "name": "signatures", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "signedMessage", + "type": "bytes" + }, + { + "internalType": "address", + "name": "stakingContractAddress", + "type": "address" + } + ], + "name": "checkNodeSignatures", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "deriveEthAddressFromPubkey", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "ethAddress", + "type": "address" + } + ], + "name": "ethAddressToPkpId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "getDerivedPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getEthAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPkpNftAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getPubkey", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + } + ], + "name": "getRootKeys", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct IPubkeyRouter.RootKey[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getRoutingData", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "internalType": "struct LibPubkeyRouterStorage.PubkeyRoutingData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isRouted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "pubkeys", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "internalType": "struct LibPubkeyRouterStorage.PubkeyRoutingData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "address", + "name": "stakingContractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "setRoutingData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "address", + "name": "stakingContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "derivedKeyId", + "type": "bytes32" + } + ], + "name": "setRoutingDataAsAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingContractAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "keyType", + "type": "uint256" + } + ], + "internalType": "struct IPubkeyRouter.RootKey[]", + "name": "newRootKeys", + "type": "tuple[]" + } + ], + "name": "voteForRootKeys", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/RateLimitNFT.abi b/abis/RateLimitNFT.abi new file mode 100644 index 0000000..94d8d4e --- /dev/null +++ b/abis/RateLimitNFT.abi @@ -0,0 +1,1385 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newAdditionalRequestsPerKilosecondCost", + "type": "uint256" + } + ], + "name": "AdditionalRequestsPerKilosecondCostSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "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": true, + "internalType": "address", + "name": "newFreeMintSigner", + "type": "address" + } + ], + "name": "FreeMintSignerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newFreeRequestsPerRateLimitWindow", + "type": "uint256" + } + ], + "name": "FreeRequestsPerRateLimitWindowSet", + "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": "newRLIHolderRateLimitWindowSeconds", + "type": "uint256" + } + ], + "name": "RLIHolderRateLimitWindowSecondsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newRateLimitWindowSeconds", + "type": "uint256" + } + ], + "name": "RateLimitWindowSecondsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrew", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestsPerKilosecond", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "sVal", + "type": "bytes32" + } + ], + "name": "freeMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newAdditionalRequestsPerKilosecondCost", + "type": "uint256" + } + ], + "name": "setAdditionalRequestsPerKilosecondCost", + "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": "address", + "name": "newFreeMintSigner", + "type": "address" + } + ], + "name": "setFreeMintSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newFreeRequestsPerRateLimitWindow", + "type": "uint256" + } + ], + "name": "setFreeRequestsPerRateLimitWindow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMaxExpirationSeconds", + "type": "uint256" + } + ], + "name": "setMaxExpirationSeconds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMaxRequestsPerKilosecond", + "type": "uint256" + } + ], + "name": "setMaxRequestsPerKilosecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newRLIHolderRateLimitWindowSeconds", + "type": "uint256" + } + ], + "name": "setRLIHolderRateLimitWindowSeconds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newRateLimitWindowSeconds", + "type": "uint256" + } + ], + "name": "setRateLimitWindowSeconds", + "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": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "RLIHolderRateLimitWindowSeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "additionalRequestsPerKilosecondCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestsPerKilosecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "calculateCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "payingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "calculateRequestsPerKilosecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "capacity", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "requestsPerKilosecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "internalType": "struct LibRateLimitNFTStorage.RateLimit", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestedRequestsPerKilosecond", + "type": "uint256" + } + ], + "name": "checkBelowMaxRequestsPerKilosecond", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentSoldRequestsPerKilosecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "defaultRateLimitWindowSeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestsPerKilosecond", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "sVal", + "type": "bytes32" + } + ], + "name": "freeMintSigTest", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "freeMintSigner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "freeRequestsPerRateLimitWindow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isExpired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxExpirationSeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxRequestsPerKilosecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "prefixed", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "redeemedFreeMints", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenIdCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenSVG", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expiresAt", + "type": "uint256" + } + ], + "name": "totalSoldRequestsPerKilosecondByExpirationTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/ReleaseRegister.abi b/abis/ReleaseRegister.abi new file mode 100644 index 0000000..fe9c0b5 --- /dev/null +++ b/abis/ReleaseRegister.abi @@ -0,0 +1,1009 @@ +[ + { + "inputs": [ + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ActivatorRoleRequired", + "type": "error" + }, + { + "inputs": [], + "name": "AdminRoleRequired", + "type": "error" + }, + { + "inputs": [], + "name": "BurnerRoleRequired", + "type": "error" + }, + { + "inputs": [], + "name": "CreatorRoleRequired", + "type": "error" + }, + { + "inputs": [], + "name": "DeactivatorRoleRequired", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEnv", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidStatus", + "type": "error" + }, + { + "inputs": [], + "name": "ReleaseNotFound", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + } + ], + "name": "AllowedAdminSigningPublicKeyAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + } + ], + "name": "AllowedAdminSigningPublicKeyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "digest", + "type": "bytes" + } + ], + "name": "AllowedAuthorKeyDigestAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "digest", + "type": "bytes" + } + ], + "name": "AllowedAuthorKeyDigestRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "AllowedEnvAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "AllowedEnvRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "subnet", + "type": "address" + } + ], + "name": "AllowedSubnetAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "subnet", + "type": "address" + } + ], + "name": "AllowedSubnetRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "domain", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "authorKeyDigest", + "type": "bytes" + } + ], + "name": "InitCreator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + } + ], + "name": "ReleaseBurned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "enum ReleaseRegister.Status", + "name": "status", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "enum ReleaseRegister.Type", + "name": "typ", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "kind", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "date", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum ReleaseRegister.Platform", + "name": "platform", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "options", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "id_key_digest", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "public_key", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "cid", + "type": "bytes" + } + ], + "name": "ReleaseCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "enum ReleaseRegister.Status", + "name": "status", + "type": "uint8" + } + ], + "name": "ReleaseStatusChange", + "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" + }, + { + "inputs": [], + "name": "ACTIVATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEACTIVATOR_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": "RELEASE_OPTION_RO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELEASE_OPTION_SSH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELEASE_OPTION_USERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + } + ], + "name": "addAllowedAdminSigningPublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "addAllowedEnv", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subnet", + "type": "address" + } + ], + "name": "addAllowedSubnet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + } + ], + "name": "burnRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + }, + { + "internalType": "enum ReleaseRegister.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + }, + { + "internalType": "enum ReleaseRegister.Type", + "name": "typ", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "kind", + "type": "bytes" + }, + { + "internalType": "enum ReleaseRegister.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "options", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id_key_digest", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "public_key", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "cid", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "date", + "type": "uint256" + } + ], + "name": "createRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + }, + { + "internalType": "enum ReleaseRegister.Type", + "name": "typ", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "kind", + "type": "bytes" + }, + { + "internalType": "enum ReleaseRegister.Platform", + "name": "platform", + "type": "uint8" + } + ], + "name": "getActiveRelease", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getActiveReleases", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatorDomain", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "releaseId", + "type": "bytes32" + } + ], + "name": "getRelease", + "outputs": [ + { + "components": [ + { + "internalType": "enum ReleaseRegister.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + }, + { + "internalType": "enum ReleaseRegister.Type", + "name": "typ", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "kind", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "date", + "type": "uint256" + }, + { + "internalType": "enum ReleaseRegister.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "options", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "id_key_digest", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "public_key", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "cid", + "type": "bytes" + } + ], + "internalType": "struct ReleaseRegister.Release", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + } + ], + "name": "hasAllowedAdminSigningPublicKey", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "digest", + "type": "bytes" + } + ], + "name": "hasAllowedAuthorKeyDigest", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "hasAllowedEnv", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subnet", + "type": "address" + } + ], + "name": "hasAllowedSubnet", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hasCreatorInit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + }, + { + "internalType": "address", + "name": "subnetId", + "type": "address" + }, + { + "internalType": "bytes", + "name": "domain", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "authorKeyDigest", + "type": "bytes" + } + ], + "name": "initCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "pubKey", + "type": "bytes" + } + ], + "name": "removeAllowedAdminSigningPublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ReleaseRegister.Env", + "name": "env", + "type": "uint8" + } + ], + "name": "removeAllowedEnv", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subnet", + "type": "address" + } + ], + "name": "removeAllowedSubnet", + "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": "bytes32", + "name": "releaseId", + "type": "bytes32" + }, + { + "internalType": "enum ReleaseRegister.Status", + "name": "status", + "type": "uint8" + } + ], + "name": "setReleaseStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/Staking.abi b/abis/Staking.abi new file mode 100644 index 0000000..2f1024a --- /dev/null +++ b/abis/Staking.abi @@ -0,0 +1,2410 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ActiveValidatorsCannotLeave", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "inputs": [], + "name": "CannotKickBelowCurrentValidatorThreshold", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingAddress", + "type": "address" + } + ], + "name": "CannotRejoinUntilNextEpochBecauseKicked", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "name": "CannotReuseCommsKeys", + "type": "error" + }, + { + "inputs": [], + "name": "CannotStakeZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "CannotVoteTwice", + "type": "error" + }, + { + "inputs": [], + "name": "CannotWithdrawZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + } + ], + "name": "CouldNotMapNodeAddressToStakerAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInActiveOrUnlockedOrPausedState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInActiveOrUnlockedState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInNextValidatorSetLockedOrReadyForNextEpochOrRestoreState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInNextValidatorSetLockedOrReadyForNextEpochState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInNextValidatorSetLockedState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "state", + "type": "uint8" + } + ], + "name": "MustBeInReadyForNextEpochState", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "MustBeValidatorInNextEpochToKick", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEndTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timeout", + "type": "uint256" + } + ], + "name": "NotEnoughTimeElapsedForTimeoutSinceLastEpoch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEndTime", + "type": "uint256" + } + ], + "name": "NotEnoughTimeElapsedSinceLastEpoch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "validatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumValidatorCount", + "type": "uint256" + } + ], + "name": "NotEnoughValidatorsInNextEpoch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentReadyValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nextReadyValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumValidatorCountToBeReady", + "type": "uint256" + } + ], + "name": "NotEnoughValidatorsReadyForNextEpoch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentEpochNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedEpochNumber", + "type": "uint256" + } + ], + "name": "SignaledReadyForWrongEpochNumber", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "StakerNotPermitted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "yourBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestedWithdrawlAmount", + "type": "uint256" + } + ], + "name": "TryingToWithdrawMoreThanStaked", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "validator", + "type": "address" + }, + { + "internalType": "address[]", + "name": "validatorsInNextEpoch", + "type": "address[]" + } + ], + "name": "ValidatorIsNotInNextEpoch", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "tolerance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kickPenaltyPercent", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LibStakingStorage.ComplaintConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "ComplaintConfigSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newTokenRewardPerTokenPerEpoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "newKeyTypes", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumValidatorCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxConcurrentRequests", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxTripleCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinTripleCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPeerCheckingIntervalSecs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxTripleConcurrency", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newRpcHealthcheckEnabled", + "type": "bool" + } + ], + "name": "ConfigSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newEpochEndTime", + "type": "uint256" + } + ], + "name": "EpochEndTimeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newEpochLength", + "type": "uint256" + } + ], + "name": "EpochLengthSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newEpochTimeout", + "type": "uint256" + } + ], + "name": "EpochTimeoutSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newKickPenaltyPercent", + "type": "uint256" + } + ], + "name": "KickPenaltyPercentSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + } + ], + "name": "ReadyForNextEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "RequestToJoin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "RequestToLeave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverContractAddress", + "type": "address" + } + ], + "name": "ResolverContractAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newStakingTokenAddress", + "type": "address" + } + ], + "name": "StakingTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum LibStakingStorage.States", + "name": "newState", + "type": "uint8" + } + ], + "name": "StateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountBurned", + "type": "uint256" + } + ], + "name": "ValidatorKickedFromNextEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "ValidatorRejoinedNextEpoch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reporter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "validatorStakerAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "VotedToKickValidatorInNextEpoch", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "validatorStakerAddress", + "type": "address" + } + ], + "name": "adminKickValidatorInNextEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "adminRejoinValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "adminResetEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "validatorStakerAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountToPenalize", + "type": "uint256" + } + ], + "name": "adminSlashValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "advanceEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "validatorStakerAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "kickValidatorInNextEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lockValidatorsForNextEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "name": "requestToJoin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestToLeave", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestToLeaveAsNode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "tolerance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kickPenaltyPercent", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.ComplaintConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setComplaintConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenRewardPerTokenPerEpoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "DEPRECATED_complaintTolerance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "DEPRECATED_complaintIntervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "keyTypes", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minimumValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxConcurrentRequests", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxTripleCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTripleCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "peerCheckingIntervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxTripleConcurrency", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "rpcHealthcheckEnabled", + "type": "bool" + } + ], + "internalType": "struct LibStakingStorage.Config", + "name": "newConfig", + "type": "tuple" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newEpochEndTime", + "type": "uint256" + } + ], + "name": "setEpochEndTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newEpochLength", + "type": "uint256" + } + ], + "name": "setEpochLength", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "newState", + "type": "uint8" + } + ], + "name": "setEpochState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newEpochTimeout", + "type": "uint256" + } + ], + "name": "setEpochTimeout", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "name": "setIpPortNodeAddressAndCommunicationPubKeys", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newKickPenaltyPercent", + "type": "uint256" + } + ], + "name": "setKickPenaltyPercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + } + ], + "name": "signalReadyForNextEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "name": "stakeAndJoin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LibStakingStorage.Version", + "name": "version", + "type": "tuple" + } + ], + "name": "VersionRequirementsUpdated", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Version", + "name": "version", + "type": "tuple" + } + ], + "name": "checkVersion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxVersion", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Version", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxVersionString", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMinVersion", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Version", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMinVersionString", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Version", + "name": "version", + "type": "tuple" + } + ], + "name": "setMaxVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "major", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "patch", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Version", + "name": "version", + "type": "tuple" + } + ], + "name": "setMinVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + } + ], + "name": "complaintConfig", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tolerance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kickPenaltyPercent", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.ComplaintConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenRewardPerTokenPerEpoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "DEPRECATED_complaintTolerance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "DEPRECATED_complaintIntervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "keyTypes", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minimumValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxConcurrentRequests", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxTripleCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTripleCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "peerCheckingIntervalSecs", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxTripleConcurrency", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "rpcHealthcheckEnabled", + "type": "bool" + } + ], + "internalType": "struct LibStakingStorage.Config", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "contractResolver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "countOfCurrentValidatorsReadyForNextEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "countOfNextValidatorsReadyForNextEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentValidatorCountForConsensus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epoch", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "epochLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "number", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "retries", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timeout", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Epoch", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getKeyTypes", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getKickedValidators", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + } + ], + "name": "getNodeStakerAddressMappings", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "internalType": "struct LibStakingStorage.AddressMapping[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingBalancesAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorsInCurrentEpoch", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorsInCurrentEpochLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorsInNextEpoch", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + } + ], + "name": "getValidatorsStructs", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Validator[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorsStructsInCurrentEpoch", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Validator[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getValidatorsStructsInNextEpoch", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Validator[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "epochNumber", + "type": "uint256" + }, + { + "internalType": "address", + "name": "validatorStakerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "voterStakerAddress", + "type": "address" + } + ], + "name": "getVotingStatusToKickValidator", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isActiveValidator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isActiveValidatorByNodeAddress", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isReadyForNextEpoch", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + } + ], + "name": "kickPenaltyPercentByReason", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextValidatorCountForConsensus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + } + ], + "name": "nodeAddressToStakerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "readyForNextEpoch", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "shouldKickValidator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "state", + "outputs": [ + { + "internalType": "enum LibStakingStorage.States", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "validators", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "ip", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ipv6", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "port", + "type": "uint32" + }, + { + "internalType": "address", + "name": "nodeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderPubKey", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverPubKey", + "type": "uint256" + } + ], + "internalType": "struct LibStakingStorage.Validator", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abis/StakingBalances.abi b/abis/StakingBalances.abi new file mode 100644 index 0000000..e091f21 --- /dev/null +++ b/abis/StakingBalances.abi @@ -0,0 +1,1215 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotAddFunctionToDiamondThatAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotAddSelectorsToZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveFunctionThatDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotRemoveImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionThatDoesNotExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + } + ], + "name": "CannotReplaceFunctionsFromFacetWithZeroAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "CannotReplaceImmutableFunction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_action", + "type": "uint8" + } + ], + "name": "IncorrectFacetCutAction", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_message", + "type": "string" + } + ], + "name": "NoBytecodeAtAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "NoSelectorsProvidedForFacetForCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_contractOwner", + "type": "address" + } + ], + "name": "NotContractOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facetAddress", + "type": "address" + } + ], + "name": "RemoveFacetAddressMustBeZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamond.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamond.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "_facetFunctionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ActiveValidatorsCannotLeave", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "aliasAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "AliasNotOwnedBySender", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "CannotRemoveAliasOfActiveValidator", + "type": "error" + }, + { + "inputs": [], + "name": "CannotStakeZero", + "type": "error" + }, + { + "inputs": [], + "name": "CannotWithdrawZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "aliasCount", + "type": "uint256" + } + ], + "name": "MaxAliasCountReached", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "OnlyStakingContract", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountStaked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumStake", + "type": "uint256" + } + ], + "name": "StakeMustBeGreaterThanMinimumStake", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountStaked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumStake", + "type": "uint256" + } + ], + "name": "StakeMustBeLessThanMaximumStake", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakerAddress", + "type": "address" + } + ], + "name": "StakerNotPermitted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "yourBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestedWithdrawlAmount", + "type": "uint256" + } + ], + "name": "TryingToWithdrawMoreThanStaked", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "AliasAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "AliasRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxAliasCount", + "type": "uint256" + } + ], + "name": "MaxAliasCountSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newMaximumStake", + "type": "uint256" + } + ], + "name": "MaximumStakeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumStake", + "type": "uint256" + } + ], + "name": "MinimumStakeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "PermittedStakerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "PermittedStakerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "permittedStakersOn", + "type": "bool" + } + ], + "name": "PermittedStakersOnChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "ResolverContractAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newTokenRewardPerTokenPerEpoch", + "type": "uint256" + } + ], + "name": "TokenRewardPerTokenPerEpochSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "ValidatorNotRewardedBecauseAlias", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ValidatorRewarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ValidatorTokensPenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "addAlias", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "addPermittedStaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "stakers", + "type": "address[]" + } + ], + "name": "addPermittedStakers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "checkStakingAmounts", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "contractResolver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "isPermittedStaker", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "penalizeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "permittedStakersOn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "aliasAccount", + "type": "address" + } + ], + "name": "removeAlias", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "removePermittedStaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "restakePenaltyTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "rewardOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "rewardValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newResolverAddress", + "type": "address" + } + ], + "name": "setContractResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMaxAliasCount", + "type": "uint256" + } + ], + "name": "setMaxAliasCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMaximumStake", + "type": "uint256" + } + ], + "name": "setMaximumStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMinimumStake", + "type": "uint256" + } + ], + "name": "setMinimumStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "permitted", + "type": "bool" + } + ], + "name": "setPermittedStakersOn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "transferPenaltyTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "withdrawPenaltyTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abis/WLIT.abi b/abis/WLIT.abi new file mode 100644 index 0000000..0d3ec92 --- /dev/null +++ b/abis/WLIT.abi @@ -0,0 +1,308 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/abis/copyAbis.ts b/abis/copyAbis.ts new file mode 100644 index 0000000..60d77d6 --- /dev/null +++ b/abis/copyAbis.ts @@ -0,0 +1,180 @@ +// npx ts-node abis/copyAbis.ts + +import { ParsedNodeContracts } from '../scripts/deployConfig'; + +const fs = require('fs'); +const path = require('path'); + +const BASE_ABI_PATH = './artifacts/contracts'; +const COPY_DIR_PATH = './'; +const CONTRACTS_DW = ['DomainWalletRegistry']; +const CONTRACTS_NODES = [ + 'PKPHelper', + 'PKPHelperV2', + 'PKPNFTMetadata', + 'PKPNFT', + 'PKPPermissions', + 'LITToken', +]; +const CONTRACTS_CORE = ['ContractResolver']; +const DEPLOYED_CONTRACTS = + process.argv[2] === 'test' + ? './deployed-dw-test-contracts.json' + : './deployed-lit-node-contracts-temp.json'; + +const NAME_TO_KEY_MAP = { + BackupRecovery: 'backupREcoveryContractAddress', + PKPNFT: 'pkpNftContractAddress', + PKPPermissions: 'pkpPermissionsContractAddress', + PaymentDelegation: 'paymentDelegationContractAddress', + PubkeyRouter: 'pubkeyRouterContractAddress', + RateLimitNFT: 'rateLimitNftContractAddress', + DomainWalletRegistry: 'domainWalletRegistryAddress', + ContractResolver: 'resolverContractAddress', + LITToken: 'LITTokenContractAddress', +}; + +const DIAMOND_CONTRACTS_TO_FACETS = { + BackupRecovery: [ + 'BackupRecoveryFacet', + 'BackupRecoveryNodeStatusFacet', + 'BackupRecoveryViewFacet', + ], + PKPNFT: ['PKPNFTFacet'], + PKPPermissions: ['PKPPermissionsFacet'], + PaymentDelegation: ['PaymentDelegationFacet'], + PubkeyRouter: ['PubkeyRouterFacet'], + RateLimitNFT: ['RateLimitNFTFacet', 'RateLimitNFTViewsFacet'], + DomainWalletRegistry: [ + 'DomainWalletRegistryFacet', + 'DomainWalletRegistryViewsFacet', + ], +}; + +function main() { + console.info('looking for deployment addresses at: ', DEPLOYED_CONTRACTS); + if (!fs.existsSync(path.join(COPY_DIR_PATH, 'abis'))) { + console.log('creating abis directory...'); + fs.mkdirSync(path.join(COPY_DIR_PATH, 'abis')); + } + + const deployedContracts: ParsedNodeContracts = JSON.parse( + fs.readFileSync(DEPLOYED_CONTRACTS).toString('utf8') + ); + + for (const contract of CONTRACTS_DW) { + const abiPath = path.join( + BASE_ABI_PATH, + 'domain-wallets', + contract + '.sol', + contract + '.json' + ); + updateAbi(abiPath, contract, deployedContracts); + copyAbi(abiPath, COPY_DIR_PATH, contract); + + if (Object.keys(DIAMOND_CONTRACTS_TO_FACETS).includes(contract)) { + // This is a diamond contract. Enumerate and copy the facets. + for (const diamondFacet of DIAMOND_CONTRACTS_TO_FACETS[ + contract as keyof typeof DIAMOND_CONTRACTS_TO_FACETS + ]) { + const facetContract = diamondFacet; + const facetAbiPath = path.join( + BASE_ABI_PATH, + 'domain-wallets', + contract, + facetContract + '.sol', + facetContract + '.json' + ); + updateAbi(facetAbiPath, contract, deployedContracts); + copyAbi(facetAbiPath, COPY_DIR_PATH, facetContract); + } + } + } + + for (const contract of CONTRACTS_NODES) { + const abiPath = path.join( + BASE_ABI_PATH, + 'lit-node', + contract + '.sol', + contract + '.json' + ); + updateAbi(abiPath, contract, deployedContracts); + copyAbi(abiPath, COPY_DIR_PATH, contract); + + if (Object.keys(DIAMOND_CONTRACTS_TO_FACETS).includes(contract)) { + // This is a diamond contract. Enumerate and copy the facets. + for (const diamondFacet of DIAMOND_CONTRACTS_TO_FACETS[ + contract as keyof typeof DIAMOND_CONTRACTS_TO_FACETS + ]) { + const facetContract = diamondFacet; + const facetAbiPath = path.join( + BASE_ABI_PATH, + 'lit-node', + contract, + facetContract + '.sol', + facetContract + '.json' + ); + updateAbi(facetAbiPath, contract, deployedContracts); + copyAbi(facetAbiPath, COPY_DIR_PATH, facetContract); + } + } + } + + for (const contract of CONTRACTS_CORE) { + const abiPath = path.join( + BASE_ABI_PATH, + 'lit-core', + contract + '.sol', + contract + '.json' + ); + updateAbi(abiPath, contract, deployedContracts); + copyAbi(abiPath, COPY_DIR_PATH, contract); + + if (Object.keys(DIAMOND_CONTRACTS_TO_FACETS).includes(contract)) { + // This is a diamond contract. Enumerate and copy the facets. + for (const diamondFacet of DIAMOND_CONTRACTS_TO_FACETS[ + contract as keyof typeof DIAMOND_CONTRACTS_TO_FACETS + ]) { + const facetContract = diamondFacet; + const facetAbiPath = path.join( + BASE_ABI_PATH, + 'lit-core', + contract, + facetContract + '.sol', + facetContract + '.json' + ); + updateAbi(facetAbiPath, contract, deployedContracts); + copyAbi(facetAbiPath, COPY_DIR_PATH, facetContract); + } + } + } + + console.log('done copying abi files'); +} + +function updateAbi( + abiPath: string, + contractName: string, + deployedContracts: ParsedNodeContracts +) { + let abi = fs.readFileSync(abiPath); + abi = abi.toString('utf8'); + abi = JSON.parse(abi); + abi.address = + deployedContracts[ + NAME_TO_KEY_MAP[ + contractName as keyof typeof NAME_TO_KEY_MAP + ] as keyof ParsedNodeContracts + ]; + fs.writeFileSync(abiPath, JSON.stringify(abi, null, 2)); +} + +function copyAbi(abiPath: string, copyDestDir: string, contractName: string) { + console.debug('copying abi at ', abiPath); + fs.copyFileSync( + path.join(abiPath), + path.join(copyDestDir, 'abis', contractName + '.json') + ); +} + +main(); diff --git a/abis/generated.ts b/abis/generated.ts new file mode 100644 index 0000000..3c647df --- /dev/null +++ b/abis/generated.ts @@ -0,0 +1,19316 @@ +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AccessControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const accessControlAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Allowlist +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const allowlistAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newAdmin', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'AdminAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newAdmin', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'AdminRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32', indexed: true }, + ], + name: 'ItemAllowed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32', indexed: true }, + ], + name: 'ItemNotAllowed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [{ name: 'newAdmin', internalType: 'address', type: 'address' }], + name: 'addAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'allowAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + name: 'allowedItems', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'isAllowed', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'newAdmin', internalType: 'address', type: 'address' }], + name: 'removeAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_allowAll', internalType: 'bool', type: 'bool' }], + name: 'setAllowAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'setAllowed', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'setNotAllowed', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BackupRecovery +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const backupRecoveryAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct BackupRecoveryArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'payable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BackupRecoveryDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const backupRecoveryDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'error', + inputs: [ + { name: 'publicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'senderPublicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'blsKey', internalType: 'bytes', type: 'bytes' }, + { name: 'senderBlsKey', internalType: 'bytes', type: 'bytes' }, + ], + name: 'BackupKeysMismatch', + }, + { + type: 'error', + inputs: [{ name: 'peer', internalType: 'address', type: 'address' }], + name: 'BackupMemberNotMappedToNode', + }, + { + type: 'error', + inputs: [{ name: 'members', internalType: 'address[]', type: 'address[]' }], + name: 'BackupSetIncomplete', + }, + { + type: 'error', + inputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + name: 'BackupStateAlreadyRegistered', + }, + { type: 'error', inputs: [], name: 'BackupStateNotRegistered' }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [{ name: 'addr', internalType: 'address', type: 'address' }], + name: 'InvalidCaller', + }, + { + type: 'error', + inputs: [{ name: 'addr', internalType: 'address', type: 'address' }], + name: 'NodesAllMappedToBackupMembers', + }, + { type: 'error', inputs: [], name: 'ProofExpired' }, + { type: 'error', inputs: [], name: 'WrongVerificationVersion' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'state', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + indexed: false, + }, + ], + name: 'BackupKeysRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'partyTheshold', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'BackupPartyRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'backupMemberAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'NodeAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'NodeAssignedToBackupMember', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'recoveryKey', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'RecoveryKeySet', + }, + { + type: 'function', + inputs: [], + name: 'BASE_EC_OP_ADDRESS', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: '_calculatePartyThreshold', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: '_checkValidatorSetForAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: '_getStakingViewFacet', + outputs: [ + { name: '', internalType: 'contract StakingViewsFacet', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'allBackupMembersMapped', + outputs: [{ name: 'mapped', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getBackupPartyState', + outputs: [ + { + name: '', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDecryptionThreshold', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMemberForNodeDkg', + outputs: [{ name: 'bp', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextBackupPartyMembers', + outputs: [ + { name: 'backupMembers', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextBackupState', + outputs: [ + { + name: 'nextState', + internalType: 'struct LibBackupRecoveryStorage.NextStateDownloadable', + type: 'tuple', + components: [ + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'registeredRecoveryKeys', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNodeAddressesForDkg', + outputs: [{ name: 'nodes', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNodeForBackupMember', + outputs: [{ name: 'peer', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'sessionId', internalType: 'bytes', type: 'bytes' }], + name: 'getPastBackupState', + outputs: [ + { + name: 'partyState', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProofSubmissionForBackupPartyMember', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakerAddressesForDkg', + outputs: [{ name: 'nodes', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isNodeForDkg', + outputs: [{ name: 'inSet', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isRecoveryDkgCompleted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'publicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'encryptedKey', internalType: 'bytes', type: 'bytes' }, + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + ], + name: 'recieveNewKeySet', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'proof', internalType: 'bytes', type: 'bytes' }], + name: 'recieveProofBls12381G1', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'proof', internalType: 'bytes', type: 'bytes' }], + name: 'recieveProofsK256', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'partyMembers', internalType: 'address[]', type: 'address[]' }, + ], + name: 'registerNewBackupParty', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'recoveryKeys', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'registerRecoveryKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'setMemberForDkg', + outputs: [{ name: 'bp', internalType: 'address', type: 'address' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'CURRENT', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clearNodeRecoveryStatus', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getNodeRecoveryStatus', + outputs: [ + { + name: '', + internalType: 'struct LibBackupRecoveryStorage.NodeRecoveryStatusMap[]', + type: 'tuple[]', + components: [ + { name: 'node_address', internalType: 'address', type: 'address' }, + { + name: 'status', + internalType: 'enum LibBackupRecoveryStorage.NodeRecoveryStatus', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'status', + internalType: 'enum LibBackupRecoveryStorage.NodeRecoveryStatus', + type: 'uint8', + }, + ], + name: 'setNodeRecoveryStatus', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { name: 'secp256K1EcdsaPubKey', internalType: 'bytes', type: 'bytes' }, + { name: 'partyMembers', internalType: 'address[]', type: 'address[]' }, + ], + name: 'setBackupPartyState', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BackupRecoveryFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const backupRecoveryFacetAbi = [ + { + type: 'error', + inputs: [ + { name: 'publicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'senderPublicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'blsKey', internalType: 'bytes', type: 'bytes' }, + { name: 'senderBlsKey', internalType: 'bytes', type: 'bytes' }, + ], + name: 'BackupKeysMismatch', + }, + { + type: 'error', + inputs: [{ name: 'peer', internalType: 'address', type: 'address' }], + name: 'BackupMemberNotMappedToNode', + }, + { + type: 'error', + inputs: [{ name: 'members', internalType: 'address[]', type: 'address[]' }], + name: 'BackupSetIncomplete', + }, + { + type: 'error', + inputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + name: 'BackupStateAlreadyRegistered', + }, + { type: 'error', inputs: [], name: 'BackupStateNotRegistered' }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [{ name: 'addr', internalType: 'address', type: 'address' }], + name: 'InvalidCaller', + }, + { + type: 'error', + inputs: [{ name: 'addr', internalType: 'address', type: 'address' }], + name: 'NodesAllMappedToBackupMembers', + }, + { type: 'error', inputs: [], name: 'ProofExpired' }, + { type: 'error', inputs: [], name: 'WrongVerificationVersion' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'state', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + indexed: false, + }, + ], + name: 'BackupKeysRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'partyTheshold', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'BackupPartyRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'backupMemberAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'NodeAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'NodeAssignedToBackupMember', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'recoveryKey', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'RecoveryKeySet', + }, + { + type: 'function', + inputs: [], + name: 'BASE_EC_OP_ADDRESS', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: '_calculatePartyThreshold', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: '_checkValidatorSetForAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: '_getStakingViewFacet', + outputs: [ + { name: '', internalType: 'contract StakingViewsFacet', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'allBackupMembersMapped', + outputs: [{ name: 'mapped', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getBackupPartyState', + outputs: [ + { + name: '', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDecryptionThreshold', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMemberForNodeDkg', + outputs: [{ name: 'bp', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextBackupPartyMembers', + outputs: [ + { name: 'backupMembers', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextBackupState', + outputs: [ + { + name: 'nextState', + internalType: 'struct LibBackupRecoveryStorage.NextStateDownloadable', + type: 'tuple', + components: [ + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'registeredRecoveryKeys', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNodeAddressesForDkg', + outputs: [{ name: 'nodes', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNodeForBackupMember', + outputs: [{ name: 'peer', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'sessionId', internalType: 'bytes', type: 'bytes' }], + name: 'getPastBackupState', + outputs: [ + { + name: 'partyState', + internalType: 'struct LibBackupRecoveryStorage.BackupRecoveryState', + type: 'tuple', + components: [ + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { + name: 'secp256K1EcdsaPubKey', + internalType: 'bytes', + type: 'bytes', + }, + { name: 'partyThreshold', internalType: 'uint256', type: 'uint256' }, + { + name: 'partyMembers', + internalType: 'address[]', + type: 'address[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProofSubmissionForBackupPartyMember', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakerAddressesForDkg', + outputs: [{ name: 'nodes', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isNodeForDkg', + outputs: [{ name: 'inSet', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isRecoveryDkgCompleted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'publicKey', internalType: 'bytes', type: 'bytes' }, + { name: 'encryptedKey', internalType: 'bytes', type: 'bytes' }, + { name: 'sessionId', internalType: 'bytes', type: 'bytes' }, + ], + name: 'recieveNewKeySet', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'proof', internalType: 'bytes', type: 'bytes' }], + name: 'recieveProofBls12381G1', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'proof', internalType: 'bytes', type: 'bytes' }], + name: 'recieveProofsK256', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'partyMembers', internalType: 'address[]', type: 'address[]' }, + ], + name: 'registerNewBackupParty', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'recoveryKeys', + internalType: 'struct LibBackupRecoveryStorage.RecoveryKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'registerRecoveryKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'setMemberForDkg', + outputs: [{ name: 'bp', internalType: 'address', type: 'address' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BackupRecoveryNodeStatusFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const backupRecoveryNodeStatusFacetAbi = [ + { + type: 'function', + inputs: [], + name: 'CURRENT', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clearNodeRecoveryStatus', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getNodeRecoveryStatus', + outputs: [ + { + name: '', + internalType: 'struct LibBackupRecoveryStorage.NodeRecoveryStatusMap[]', + type: 'tuple[]', + components: [ + { name: 'node_address', internalType: 'address', type: 'address' }, + { + name: 'status', + internalType: 'enum LibBackupRecoveryStorage.NodeRecoveryStatus', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'status', + internalType: 'enum LibBackupRecoveryStorage.NodeRecoveryStatus', + type: 'uint8', + }, + ], + name: 'setNodeRecoveryStatus', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BackupRecoveryTestFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const backupRecoveryTestFacetAbi = [ + { + type: 'function', + inputs: [ + { name: 'bls12381G1EncKey', internalType: 'bytes', type: 'bytes' }, + { name: 'secp256K1EcdsaPubKey', internalType: 'bytes', type: 'bytes' }, + { name: 'partyMembers', internalType: 'address[]', type: 'address[]' }, + ], + name: 'setBackupPartyState', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ContextUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const contextUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ContractResolver +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const contractResolverAbi = [ + { + type: 'constructor', + inputs: [ + { name: 'env', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'AdminRoleRequired' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + indexed: false, + }, + ], + name: 'AllowedEnvAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + indexed: false, + }, + ], + name: 'AllowedEnvRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'typ', internalType: 'bytes32', type: 'bytes32', indexed: false }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + indexed: false, + }, + { + name: 'addr', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'SetContract', + }, + { + type: 'function', + inputs: [], + name: 'ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'ALLOWLIST_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'BACKUP_RECOVERY_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_WALLET_REGISTRY', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'HD_KEY_DERIVER_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'LIT_TOKEN_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MULTI_SENDER_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PKP_HELPER_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PKP_NFT_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PKP_NFT_METADATA_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PKP_PERMISSIONS_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PUB_KEY_ROUTER_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'RATE_LIMIT_NFT_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'RELEASE_REGISTER_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'STAKING_BALANCES_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'STAKING_CONTRACT', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'newAdmin', internalType: 'address', type: 'address' }], + name: 'addAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + name: 'addAllowedEnv', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'typ', internalType: 'bytes32', type: 'bytes32' }, + { name: 'env', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + name: 'getContract', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'adminBeingRemoved', internalType: 'address', type: 'address' }, + ], + name: 'removeAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + name: 'removeAllowedEnv', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'typ', internalType: 'bytes32', type: 'bytes32' }, + { name: 'env', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + { name: 'addr', internalType: 'address', type: 'address' }, + ], + name: 'setContract', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: '', internalType: 'bytes32', type: 'bytes32' }, + { name: '', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + name: 'typeAddresses', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DevKeyDeriver +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const devKeyDeriverAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [ + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'rootHDKeys', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + name: 'computeHDPubKey', + outputs: [ + { name: '', internalType: 'bool', type: 'bool' }, + { name: '', internalType: 'bytes', type: 'bytes' }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DiamondCutFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const diamondCutFacetAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DiamondInit +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const diamondInitAbi = [ + { + type: 'function', + inputs: [], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DiamondLoupeFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const diamondLoupeFacetAbi = [ + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DiamondLoupeFacetNoERC165 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const diamondLoupeFacetNoErc165Abi = [ + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DiamondMultiInit +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const diamondMultiInitAbi = [ + { + type: 'error', + inputs: [ + { name: '_addressesLength', internalType: 'uint256', type: 'uint256' }, + { name: '_calldataLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'AddressAndCalldataLengthDoNotMatch', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'function', + inputs: [ + { name: '_addresses', internalType: 'address[]', type: 'address[]' }, + { name: '_calldata', internalType: 'bytes[]', type: 'bytes[]' }, + ], + name: 'multiInit', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DomainWalletRegistry +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const domainWalletRegistryAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct ConstructorArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'payable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DomainWalletRegistryDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const domainWalletRegistryDiamondAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [ + { name: 'metadataCount', internalType: 'uint256', type: 'uint256' }, + { name: 'validMetadataCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InvalidNftMetadataCollectionLength', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'ttl', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Expired', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'id', internalType: 'uint64', type: 'uint64', indexed: false }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { name: 'ttl', internalType: 'uint256', type: 'uint256', indexed: false }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Registered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'Removed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'Revoked', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'hasExpired', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'userId', internalType: 'bytes', type: 'bytes' }, + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'ttl', internalType: 'uint256', type: 'uint256' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'registerDomain', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'userId', internalType: 'bytes', type: 'bytes' }, + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'ttl', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'registerDomainAndMintNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'id', internalType: 'uint64', type: 'uint64' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'registerPKP', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'removeDomain', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'revokeDomain', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'setPKPMetadata', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'record', internalType: 'bytes', type: 'bytes' }, + ], + name: 'updateDomainRecord', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'error', + inputs: [ + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'DomainAlreadyRegistered', + }, + { + type: 'function', + inputs: [{ name: 'uri', internalType: 'bytes', type: 'bytes' }], + name: 'checkRegistration', + outputs: [], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getDomainIdByTokenId', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'uri', internalType: 'bytes', type: 'bytes' }], + name: 'getDomainTokenIdByUri', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getDomainUri', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainWalletRegistryAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getExpiration', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpHelperAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'id', internalType: 'uint64', type: 'uint64' }], + name: 'getPkpTokenId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getRecord', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'hasOwner', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isOwner', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isRouted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DomainWalletRegistryFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const domainWalletRegistryFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [ + { name: 'metadataCount', internalType: 'uint256', type: 'uint256' }, + { name: 'validMetadataCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InvalidNftMetadataCollectionLength', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'ttl', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Expired', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'id', internalType: 'uint64', type: 'uint64', indexed: false }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { name: 'ttl', internalType: 'uint256', type: 'uint256', indexed: false }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Registered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'Removed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'subDomain', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'Revoked', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'hasExpired', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'userId', internalType: 'bytes', type: 'bytes' }, + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'ttl', internalType: 'uint256', type: 'uint256' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'registerDomain', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'userId', internalType: 'bytes', type: 'bytes' }, + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'ttl', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'registerDomainAndMintNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'id', internalType: 'uint64', type: 'uint64' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'registerPKP', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'removeDomain', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'revokeDomain', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'setPKPMetadata', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'record', internalType: 'bytes', type: 'bytes' }, + ], + name: 'updateDomainRecord', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DomainWalletRegistryViewsFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const domainWalletRegistryViewsFacetAbi = [ + { + type: 'error', + inputs: [ + { name: 'uri', internalType: 'bytes', type: 'bytes' }, + { name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'DomainAlreadyRegistered', + }, + { + type: 'function', + inputs: [{ name: 'uri', internalType: 'bytes', type: 'bytes' }], + name: 'checkRegistration', + outputs: [], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getDomainIdByTokenId', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'uri', internalType: 'bytes', type: 'bytes' }], + name: 'getDomainTokenIdByUri', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getDomainUri', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainWalletRegistryAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getExpiration', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpHelperAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'id', internalType: 'uint64', type: 'uint64' }], + name: 'getPkpTokenId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getRecord', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'hasOwner', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isOwner', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pkpTokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isRouted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EIP712 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const eip712Abi = [ + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', + }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC165 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc165Abi = [ + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC165Upgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc165UpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20Abi = [ + { + type: 'constructor', + inputs: [ + { name: 'name_', internalType: 'string', type: 'string' }, + { name: 'symbol_', internalType: 'string', type: 'string' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20Burnable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20BurnableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20Capped +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20CappedAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'cap', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20Pausable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20PausableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Paused', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Unpaused', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'paused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20Permit +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20PermitAbi = [ + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC20Votes +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20VotesAbi = [ + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'fromDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'previousBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DelegateVotesChanged', + }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'pos', internalType: 'uint32', type: 'uint32' }, + ], + name: 'checkpoints', + outputs: [ + { + name: '', + internalType: 'struct ERC20Votes.Checkpoint', + type: 'tuple', + components: [ + { name: 'fromBlock', internalType: 'uint32', type: 'uint32' }, + { name: 'votes', internalType: 'uint224', type: 'uint224' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clock', + outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegatee', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'delegates', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'numCheckpoints', + outputs: [{ name: '', internalType: 'uint32', type: 'uint32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC721BurnableUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc721BurnableUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC721EnumerableUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc721EnumerableUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ERC721Upgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc721UpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IAccessControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iAccessControlAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iDiamondAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IDiamondCut +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iDiamondCutAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IDiamondLoupe +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iDiamondLoupeAbi = [ + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: 'facetFunctionSelectors_', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC173 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc173Abi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC20 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc20Abi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC20Metadata +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc20MetadataAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC20Permit +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc20PermitAbi = [ + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC5267 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc5267Abi = [ + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC5805 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc5805Abi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'fromDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'previousBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DelegateVotesChanged', + }, + { + type: 'function', + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clock', + outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegatee', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'delegates', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC6372 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc6372Abi = [ + { + type: 'function', + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clock', + outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721Abi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721Enumerable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721EnumerableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721EnumerableUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721EnumerableUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721Metadata +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721MetadataAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721MetadataUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721MetadataUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721Receiver +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721ReceiverAbi = [ + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onERC721Received', + outputs: [{ name: '', internalType: 'bytes4', type: 'bytes4' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721ReceiverUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721ReceiverUpgradeableAbi = [ + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onERC721Received', + outputs: [{ name: '', internalType: 'bytes4', type: 'bytes4' }], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IERC721Upgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ierc721UpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IKeyDeriver +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iKeyDeriverAbi = [ + { + type: 'function', + inputs: [ + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'rootHDKeys', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + name: 'computeHDPubKey', + outputs: [ + { name: '', internalType: 'bool', type: 'bool' }, + { name: '', internalType: 'bytes', type: 'bytes' }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IVotes +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const iVotesAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'fromDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'previousBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DelegateVotesChanged', + }, + { + type: 'function', + inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegatee', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'delegates', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Initializable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const initializableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// KeyDeriver +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const keyDeriverAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [], + name: 'HD_KDF', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'rootHDKeys', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + name: 'computeHDPubKey', + outputs: [ + { name: '', internalType: 'bool', type: 'bool' }, + { name: '', internalType: 'bytes', type: 'bytes' }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// LITToken +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const litTokenAbi = [ + { + type: 'constructor', + inputs: [{ name: 'cap', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'fromDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'previousBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newBalance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DelegateVotesChanged', + }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Paused', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Unpaused', + }, + { + type: 'function', + inputs: [], + name: 'ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MINTER_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'PAUSER_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'cap', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'pos', internalType: 'uint32', type: 'uint32' }, + ], + name: 'checkpoints', + outputs: [ + { + name: '', + internalType: 'struct ERC20Votes.Checkpoint', + type: 'tuple', + components: [ + { name: 'fromBlock', internalType: 'uint32', type: 'uint32' }, + { name: 'votes', internalType: 'uint224', type: 'uint224' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clock', + outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'subtractedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegatee', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'delegates', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_recipient', internalType: 'address', type: 'address' }, + { name: '_amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'numCheckpoints', + outputs: [{ name: '', internalType: 'uint32', type: 'uint32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'paused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// LibDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const libDiamondAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Multisender +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const multisenderAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_recipients', internalType: 'address[]', type: 'address[]' }, + ], + name: 'sendEth', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: '_recipients', internalType: 'address[]', type: 'address[]' }, + { name: 'tokenContract', internalType: 'address', type: 'address' }, + ], + name: 'sendTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenContract', internalType: 'address', type: 'address' }, + ], + name: 'withdrawTokens', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Ownable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ownableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OwnershipFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const ownershipFacetAbi = [ + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPHelper +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpHelperAbi = [ + { + type: 'constructor', + inputs: [ + { name: '_resolver', internalType: 'address', type: 'address' }, + { + name: '_env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'claimMaterial', + internalType: 'struct LibPKPNFTStorage.ClaimMaterial', + type: 'tuple', + components: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + ], + }, + { + name: 'authMethodData', + internalType: 'struct PKPHelper.AuthMethodData', + type: 'tuple', + components: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedIpfsCIDs', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedIpfsCIDScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAddresses', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'permittedAddressScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'addPkpEthAddressAsPermittedAddress', + internalType: 'bool', + type: 'bool', + }, + { name: 'sendPkpToItself', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'claimAndMintNextAndAddAuthMethods', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'claimMaterial', + internalType: 'struct LibPKPNFTStorage.ClaimMaterial', + type: 'tuple', + components: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + ], + }, + { + name: 'authMethodData', + internalType: 'struct PKPHelper.AuthMethodData', + type: 'tuple', + components: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedIpfsCIDs', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedIpfsCIDScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAddresses', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'permittedAddressScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'addPkpEthAddressAsPermittedAddress', + internalType: 'bool', + type: 'bool', + }, + { name: 'sendPkpToItself', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'claimAndMintNextAndAddAuthMethodsWithTypes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [ + { name: '', internalType: 'contract ContractResolver', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'env', + outputs: [ + { name: '', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainWalletRegistry', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPKPNftMetdataAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpPermissionsAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'addPkpEthAddressAsPermittedAddress', + internalType: 'bool', + type: 'bool', + }, + { name: 'sendPkpToItself', internalType: 'bool', type: 'bool' }, + ], + name: 'mintNextAndAddAuthMethods', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'permittedIpfsCIDs', internalType: 'bytes[]', type: 'bytes[]' }, + { + name: 'permittedIpfsCIDScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAddresses', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'permittedAddressScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'addPkpEthAddressAsPermittedAddress', + internalType: 'bool', + type: 'bool', + }, + { name: 'sendPkpToItself', internalType: 'bool', type: 'bool' }, + ], + name: 'mintNextAndAddAuthMethodsWithTypes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypes', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIds', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeys', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopes', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + { + name: 'addPkpEthAddressAsPermittedAddress', + internalType: 'bool', + type: 'bool', + }, + { name: 'sendPkpToItself', internalType: 'bool', type: 'bool' }, + ], + name: 'mintNextAndAddDomainWalletMetadata', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onERC721Received', + outputs: [{ name: '', internalType: 'bytes4', type: 'bytes4' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'removePkpMetadata', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'nftMetadata', internalType: 'string[]', type: 'string[]' }, + ], + name: 'setPkpMetadata', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPNFT +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpnftAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct StakingArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'payable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPNFTDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpnftDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeMintSigner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'FreeMintSignerSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMintCost', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MintCostSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'PKPMinted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrew', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + ], + name: 'claimAndMint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'exists', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeMintSigner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextDerivedKeyId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftMetadataAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpPermissionsAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRouterAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakingAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'mintCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'mintGrantAndBurnNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'keyType', internalType: 'uint256', type: 'uint256' }], + name: 'mintNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'hash', internalType: 'bytes32', type: 'bytes32' }], + name: 'prefixed', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'redeemedFreeMintIds', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newFreeMintSigner', internalType: 'address', type: 'address' }, + ], + name: 'setFreeMintSigner', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newMintCost', internalType: 'uint256', type: 'uint256' }], + name: 'setMintCost', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPNFTFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpnftFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeMintSigner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'FreeMintSignerSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMintCost', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MintCostSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'PKPMinted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrew', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + ], + name: 'claimAndMint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'exists', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeMintSigner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextDerivedKeyId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftMetadataAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpPermissionsAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRouterAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakingAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'mintCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'mintGrantAndBurnNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'keyType', internalType: 'uint256', type: 'uint256' }], + name: 'mintNext', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'hash', internalType: 'bytes32', type: 'bytes32' }], + name: 'prefixed', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'redeemedFreeMintIds', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newFreeMintSigner', internalType: 'address', type: 'address' }, + ], + name: 'setFreeMintSigner', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newMintCost', internalType: 'uint256', type: 'uint256' }], + name: 'setMintCost', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPNFTMetadata +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpnftMetadataAbi = [ + { + type: 'constructor', + inputs: [ + { name: '_resolver', internalType: 'address', type: 'address' }, + { + name: '_env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'buffer', internalType: 'bytes', type: 'bytes' }], + name: 'bytesToHex', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [ + { name: '', internalType: 'contract ContractResolver', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'env', + outputs: [ + { name: '', internalType: 'enum ContractResolver.Env', type: 'uint8' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'removeProfileForPkp', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'removeUrlForPKP', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'imgUrl', internalType: 'string', type: 'string' }, + ], + name: 'setProfileForPKP', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'url', internalType: 'string', type: 'string' }, + ], + name: 'setUrlForPKP', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'pubKey', internalType: 'bytes', type: 'bytes' }, + { name: 'ethAddress', internalType: 'address', type: 'address' }, + ], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPPermissions +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpPermissionsAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct PKPPermissionsArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'nonpayable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPPermissionsDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpPermissionsDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'userPubkey', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'PermittedAuthMethodAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'PermittedAuthMethodRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'scopeId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'PermittedAuthMethodScopeAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'scopeId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'PermittedAuthMethodScopeRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'group', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'root', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + ], + name: 'RootHashUpdated', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAction', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { + name: 'authMethod', + internalType: 'struct LibPKPPermissionsStorage.AuthMethod', + type: 'tuple', + components: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'userPubkey', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAuthMethod', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'addPermittedAuthMethodScope', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypesToAdd', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIdsToAdd', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeysToAdd', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopesToAdd', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAuthMethodTypesToRemove', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIdsToRemove', + internalType: 'bytes[]', + type: 'bytes[]', + }, + ], + name: 'batchAddRemoveAuthMethods', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getAuthMethodId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedActions', + outputs: [{ name: '', internalType: 'bytes[]', type: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedAddresses', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'maxScopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPermittedAuthMethodScopes', + outputs: [{ name: '', internalType: 'bool[]', type: 'bool[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedAuthMethods', + outputs: [ + { + name: '', + internalType: 'struct LibPKPPermissionsStorage.AuthMethod[]', + type: 'tuple[]', + components: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'userPubkey', internalType: 'bytes', type: 'bytes' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRouterAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getTokenIdsForAuthMethod', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getUserPubkeyForAuthMethod', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'isPermittedAction', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'isPermittedAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'isPermittedAuthMethod', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'isPermittedAuthMethodScopePresent', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'removePermittedAction', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'removePermittedAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'removePermittedAuthMethod', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'removePermittedAuthMethodScope', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'root', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRootHash', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'leaf', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'verifyState', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'proofFlags', internalType: 'bool[]', type: 'bool[]' }, + { name: 'leaves', internalType: 'bytes32[]', type: 'bytes32[]' }, + ], + name: 'verifyStates', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PKPPermissionsFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pkpPermissionsFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'userPubkey', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'PermittedAuthMethodAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'PermittedAuthMethodRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'scopeId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'PermittedAuthMethodScopeAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'authMethodType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'id', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'scopeId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'PermittedAuthMethodScopeRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'group', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'root', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + ], + name: 'RootHashUpdated', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAction', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { + name: 'authMethod', + internalType: 'struct LibPKPPermissionsStorage.AuthMethod', + type: 'tuple', + components: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'userPubkey', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'scopes', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'addPermittedAuthMethod', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'addPermittedAuthMethodScope', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { + name: 'permittedAuthMethodTypesToAdd', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIdsToAdd', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodPubkeysToAdd', + internalType: 'bytes[]', + type: 'bytes[]', + }, + { + name: 'permittedAuthMethodScopesToAdd', + internalType: 'uint256[][]', + type: 'uint256[][]', + }, + { + name: 'permittedAuthMethodTypesToRemove', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'permittedAuthMethodIdsToRemove', + internalType: 'bytes[]', + type: 'bytes[]', + }, + ], + name: 'batchAddRemoveAuthMethods', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getAuthMethodId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedActions', + outputs: [{ name: '', internalType: 'bytes[]', type: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedAddresses', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'maxScopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPermittedAuthMethodScopes', + outputs: [{ name: '', internalType: 'bool[]', type: 'bool[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPermittedAuthMethods', + outputs: [ + { + name: '', + internalType: 'struct LibPKPPermissionsStorage.AuthMethod[]', + type: 'tuple[]', + components: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'userPubkey', internalType: 'bytes', type: 'bytes' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRouterAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getTokenIdsForAuthMethod', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'getUserPubkeyForAuthMethod', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'isPermittedAction', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'isPermittedAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'isPermittedAuthMethod', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'isPermittedAuthMethodScopePresent', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'ipfsCID', internalType: 'bytes', type: 'bytes' }, + ], + name: 'removePermittedAction', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'removePermittedAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + ], + name: 'removePermittedAuthMethod', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'authMethodType', internalType: 'uint256', type: 'uint256' }, + { name: 'id', internalType: 'bytes', type: 'bytes' }, + { name: 'scopeId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'removePermittedAuthMethodScope', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'root', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRootHash', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'leaf', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'verifyState', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'group', internalType: 'uint256', type: 'uint256' }, + { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'proofFlags', internalType: 'bool[]', type: 'bool[]' }, + { name: 'leaves', internalType: 'bytes32[]', type: 'bytes32[]' }, + ], + name: 'verifyStates', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Pausable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pausableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Paused', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'Unpaused', + }, + { + type: 'function', + inputs: [], + name: 'paused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PaymentDelegation +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const paymentDelegationAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct PaymentDelegationArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'nonpayable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PaymentDelegationFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const paymentDelegationFacetAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'payer', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + ], + name: 'DelegationCreated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'payer', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + ], + name: 'DelegationRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'payer', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'restriction', + internalType: 'struct LibPaymentDelegationStorage.Restriction', + type: 'tuple', + components: [ + { + name: 'requestsPerPeriod', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'periodSeconds', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'RestrictionSet', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'delegatePayments', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'users', internalType: 'address[]', type: 'address[]' }], + name: 'delegatePaymentsBatch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'getPayerAndRestriction', + outputs: [ + { name: '', internalType: 'address', type: 'address' }, + { + name: '', + internalType: 'struct LibPaymentDelegationStorage.Restriction', + type: 'tuple', + components: [ + { + name: 'requestsPerPeriod', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'periodSeconds', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], + name: 'getRestriction', + outputs: [ + { + name: '', + internalType: 'struct LibPaymentDelegationStorage.Restriction', + type: 'tuple', + components: [ + { + name: 'requestsPerPeriod', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'periodSeconds', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], + name: 'getUsers', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'r', + internalType: 'struct LibPaymentDelegationStorage.Restriction', + type: 'tuple', + components: [ + { + name: 'requestsPerPeriod', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'periodSeconds', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'setRestriction', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'undelegatePayments', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'users', internalType: 'address[]', type: 'address[]' }], + name: 'undelegatePaymentsBatch', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PubkeyRouter +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pubkeyRouterAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct PubkeyRouterArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'nonpayable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PubkeyRouterDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pubkeyRouterDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'stakingContract', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'keyType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'derivedKeyId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + ], + name: 'PubkeyRoutingDataSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'stakingContract', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'rootKey', + internalType: 'struct IPubkeyRouter.RootKey', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'RootKeySet', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + ], + name: 'adminResetRootKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + { name: 'signedMessage', internalType: 'bytes', type: 'bytes' }, + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + ], + name: 'checkNodeSignatures', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + name: 'deriveEthAddressFromPubkey', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'ethAddress', internalType: 'address', type: 'address' }], + name: 'ethAddressToPkpId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'getDerivedPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + ], + name: 'getRootKeys', + outputs: [ + { + name: '', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getRoutingData', + outputs: [ + { + name: '', + internalType: 'struct LibPubkeyRouterStorage.PubkeyRoutingData', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isRouted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'pubkeys', + outputs: [ + { + name: '', + internalType: 'struct LibPubkeyRouterStorage.PubkeyRoutingData', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRoutingData', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'stakingContract', internalType: 'address', type: 'address' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRoutingDataAsAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'newRootKeys', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'voteForRootKeys', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PubkeyRouterFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const pubkeyRouterFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ContractResolverAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'stakingContract', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'keyType', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'derivedKeyId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + ], + name: 'PubkeyRoutingDataSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'stakingContract', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'rootKey', + internalType: 'struct IPubkeyRouter.RootKey', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'RootKeySet', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + ], + name: 'adminResetRootKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'signatures', + internalType: 'struct IPubkeyRouter.Signature[]', + type: 'tuple[]', + components: [ + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + ], + }, + { name: 'signedMessage', internalType: 'bytes', type: 'bytes' }, + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + ], + name: 'checkNodeSignatures', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + name: 'deriveEthAddressFromPubkey', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'ethAddress', internalType: 'address', type: 'address' }], + name: 'ethAddressToPkpId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'getDerivedPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getEthAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPkpNftAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getPubkey', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakingContract', internalType: 'address', type: 'address' }, + ], + name: 'getRootKeys', + outputs: [ + { + name: '', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getRoutingData', + outputs: [ + { + name: '', + internalType: 'struct LibPubkeyRouterStorage.PubkeyRoutingData', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isRouted', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'pubkeys', + outputs: [ + { + name: '', + internalType: 'struct LibPubkeyRouterStorage.PubkeyRoutingData', + type: 'tuple', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRoutingData', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'stakingContract', internalType: 'address', type: 'address' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + { name: 'derivedKeyId', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setRoutingDataAsAdmin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'stakingContractAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'newRootKeys', + internalType: 'struct IPubkeyRouter.RootKey[]', + type: 'tuple[]', + components: [ + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'keyType', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'voteForRootKeys', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RateLimitNFT +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const rateLimitNftAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct StakingArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'payable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RateLimitNFTDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const rateLimitNftDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newAdditionalRequestsPerKilosecondCost', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'AdditionalRequestsPerKilosecondCostSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeMintSigner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'FreeMintSignerSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeRequestsPerRateLimitWindow', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'FreeRequestsPerRateLimitWindowSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newRLIHolderRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RLIHolderRateLimitWindowSecondsSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RateLimitWindowSecondsSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrew', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sVal', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'freeMint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'expiresAt', internalType: 'uint256', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newAdditionalRequestsPerKilosecondCost', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setAdditionalRequestsPerKilosecondCost', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newFreeMintSigner', internalType: 'address', type: 'address' }, + ], + name: 'setFreeMintSigner', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newFreeRequestsPerRateLimitWindow', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setFreeRequestsPerRateLimitWindow', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newMaxExpirationSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setMaxExpirationSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newMaxRequestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setMaxRequestsPerKilosecond', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newRLIHolderRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setRLIHolderRateLimitWindowSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setRateLimitWindowSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'RLIHolderRateLimitWindowSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'additionalRequestsPerKilosecondCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + name: 'calculateCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'payingAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + name: 'calculateRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'capacity', + outputs: [ + { + name: '', + internalType: 'struct LibRateLimitNFTStorage.RateLimit', + type: 'tuple', + components: [ + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'requestedRequestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'checkBelowMaxRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'currentSoldRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'defaultRateLimitWindowSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sVal', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'freeMintSigTest', + outputs: [], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeMintSigner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeRequestsPerRateLimitWindow', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isExpired', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maxExpirationSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maxRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'hash', internalType: 'bytes32', type: 'bytes32' }], + name: 'prefixed', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }], + name: 'redeemedFreeMints', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'tokenIdCounter', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenSVG', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'expiresAt', internalType: 'uint256', type: 'uint256' }], + name: 'totalSoldRequestsPerKilosecondByExpirationTime', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RateLimitNFTFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const rateLimitNftFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newAdditionalRequestsPerKilosecondCost', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'AdditionalRequestsPerKilosecondCostSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeMintSigner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'FreeMintSignerSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newFreeRequestsPerRateLimitWindow', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'FreeRequestsPerRateLimitWindowSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newRLIHolderRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RLIHolderRateLimitWindowSecondsSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RateLimitWindowSecondsSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrew', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sVal', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'freeMint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'expiresAt', internalType: 'uint256', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newAdditionalRequestsPerKilosecondCost', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setAdditionalRequestsPerKilosecondCost', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newFreeMintSigner', internalType: 'address', type: 'address' }, + ], + name: 'setFreeMintSigner', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newFreeRequestsPerRateLimitWindow', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setFreeRequestsPerRateLimitWindow', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newMaxExpirationSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setMaxExpirationSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newMaxRequestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setMaxRequestsPerKilosecond', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newRLIHolderRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setRLIHolderRateLimitWindowSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newRateLimitWindowSeconds', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setRateLimitWindowSeconds', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'index', internalType: 'uint256', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'tokenId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RateLimitNFTViewsFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const rateLimitNftViewsFacetAbi = [ + { + type: 'function', + inputs: [], + name: 'RLIHolderRateLimitWindowSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'additionalRequestsPerKilosecondCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + name: 'calculateCost', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'payingAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + name: 'calculateRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'capacity', + outputs: [ + { + name: '', + internalType: 'struct LibRateLimitNFTStorage.RateLimit', + type: 'tuple', + components: [ + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'requestedRequestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'checkBelowMaxRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'currentSoldRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'defaultRateLimitWindowSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'expiresAt', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestsPerKilosecond', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sVal', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'freeMintSigTest', + outputs: [], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeMintSigner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'freeRequestsPerRateLimitWindow', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'isExpired', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maxExpirationSeconds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maxRequestsPerKilosecond', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'hash', internalType: 'bytes32', type: 'bytes32' }], + name: 'prefixed', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'msgHash', internalType: 'bytes32', type: 'bytes32' }], + name: 'redeemedFreeMints', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'tokenIdCounter', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'tokenId', internalType: 'uint256', type: 'uint256' }], + name: 'tokenSVG', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'expiresAt', internalType: 'uint256', type: 'uint256' }], + name: 'totalSoldRequestsPerKilosecondByExpirationTime', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ReentrancyGuardUpgradeable +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const reentrancyGuardUpgradeableAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'version', internalType: 'uint8', type: 'uint8', indexed: false }, + ], + name: 'Initialized', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ReleaseRegister +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const releaseRegisterAbi = [ + { + type: 'constructor', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + ], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'ActivatorRoleRequired' }, + { type: 'error', inputs: [], name: 'AdminRoleRequired' }, + { type: 'error', inputs: [], name: 'BurnerRoleRequired' }, + { type: 'error', inputs: [], name: 'CreatorRoleRequired' }, + { type: 'error', inputs: [], name: 'DeactivatorRoleRequired' }, + { type: 'error', inputs: [], name: 'InvalidEnv' }, + { type: 'error', inputs: [], name: 'InvalidStatus' }, + { type: 'error', inputs: [], name: 'ReleaseNotFound' }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'pubKey', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'AllowedAdminSigningPublicKeyAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'pubKey', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'AllowedAdminSigningPublicKeyRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'digest', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'AllowedAuthorKeyDigestAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'digest', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'AllowedAuthorKeyDigestRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'env', + internalType: 'enum ReleaseRegister.Env', + type: 'uint8', + indexed: false, + }, + ], + name: 'AllowedEnvAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'env', + internalType: 'enum ReleaseRegister.Env', + type: 'uint8', + indexed: false, + }, + ], + name: 'AllowedEnvRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'subnet', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AllowedSubnetAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'subnet', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AllowedSubnetRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'domain', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'authorKeyDigest', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'InitCreator', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'releaseId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + ], + name: 'ReleaseBurned', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'releaseId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'status', + internalType: 'enum ReleaseRegister.Status', + type: 'uint8', + indexed: false, + }, + { + name: 'env', + internalType: 'enum ReleaseRegister.Env', + type: 'uint8', + indexed: false, + }, + { + name: 'typ', + internalType: 'enum ReleaseRegister.Type', + type: 'uint8', + indexed: false, + }, + { name: 'kind', internalType: 'bytes', type: 'bytes', indexed: false }, + { + name: 'date', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'platform', + internalType: 'enum ReleaseRegister.Platform', + type: 'uint8', + indexed: false, + }, + { + name: 'options', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'id_key_digest', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { + name: 'public_key', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + { name: 'cid', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'ReleaseCreated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'releaseId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'status', + internalType: 'enum ReleaseRegister.Status', + type: 'uint8', + indexed: false, + }, + ], + name: 'ReleaseStatusChange', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'function', + inputs: [], + name: 'ACTIVATOR_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'BURNER_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'CREATOR_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DEACTIVATOR_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'RELEASE_OPTION_RO', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'RELEASE_OPTION_SSH', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'RELEASE_OPTION_USERS', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pubKey', internalType: 'bytes', type: 'bytes' }], + name: 'addAllowedAdminSigningPublicKey', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + ], + name: 'addAllowedEnv', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'subnet', internalType: 'address', type: 'address' }], + name: 'addAllowedSubnet', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'releaseId', internalType: 'bytes32', type: 'bytes32' }], + name: 'burnRelease', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'releaseId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'status', + internalType: 'enum ReleaseRegister.Status', + type: 'uint8', + }, + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + { name: 'typ', internalType: 'enum ReleaseRegister.Type', type: 'uint8' }, + { name: 'kind', internalType: 'bytes', type: 'bytes' }, + { + name: 'platform', + internalType: 'enum ReleaseRegister.Platform', + type: 'uint8', + }, + { name: 'options', internalType: 'uint256', type: 'uint256' }, + { name: 'id_key_digest', internalType: 'bytes', type: 'bytes' }, + { name: 'public_key', internalType: 'bytes', type: 'bytes' }, + { name: 'cid', internalType: 'bytes', type: 'bytes' }, + { name: 'date', internalType: 'uint256', type: 'uint256' }, + ], + name: 'createRelease', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + { name: 'typ', internalType: 'enum ReleaseRegister.Type', type: 'uint8' }, + { name: 'kind', internalType: 'bytes', type: 'bytes' }, + { + name: 'platform', + internalType: 'enum ReleaseRegister.Platform', + type: 'uint8', + }, + ], + name: 'getActiveRelease', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getActiveReleases', + outputs: [{ name: '', internalType: 'bytes32[]', type: 'bytes32[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getCreatorDomain', + outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'releaseId', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRelease', + outputs: [ + { + name: '', + internalType: 'struct ReleaseRegister.Release', + type: 'tuple', + components: [ + { + name: 'status', + internalType: 'enum ReleaseRegister.Status', + type: 'uint8', + }, + { + name: 'env', + internalType: 'enum ReleaseRegister.Env', + type: 'uint8', + }, + { + name: 'typ', + internalType: 'enum ReleaseRegister.Type', + type: 'uint8', + }, + { name: 'kind', internalType: 'bytes', type: 'bytes' }, + { name: 'date', internalType: 'uint256', type: 'uint256' }, + { + name: 'platform', + internalType: 'enum ReleaseRegister.Platform', + type: 'uint8', + }, + { name: 'options', internalType: 'uint256', type: 'uint256' }, + { name: 'id_key_digest', internalType: 'bytes', type: 'bytes' }, + { name: 'public_key', internalType: 'bytes', type: 'bytes' }, + { name: 'cid', internalType: 'bytes', type: 'bytes' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pubKey', internalType: 'bytes', type: 'bytes' }], + name: 'hasAllowedAdminSigningPublicKey', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'digest', internalType: 'bytes', type: 'bytes' }], + name: 'hasAllowedAuthorKeyDigest', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + ], + name: 'hasAllowedEnv', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'subnet', internalType: 'address', type: 'address' }], + name: 'hasAllowedSubnet', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'hasCreatorInit', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + { name: 'subnetId', internalType: 'address', type: 'address' }, + { name: 'domain', internalType: 'bytes', type: 'bytes' }, + { name: 'authorKeyDigest', internalType: 'bytes', type: 'bytes' }, + ], + name: 'initCreator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'pubKey', internalType: 'bytes', type: 'bytes' }], + name: 'removeAllowedAdminSigningPublicKey', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'env', internalType: 'enum ReleaseRegister.Env', type: 'uint8' }, + ], + name: 'removeAllowedEnv', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'subnet', internalType: 'address', type: 'address' }], + name: 'removeAllowedSubnet', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'releaseId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'status', + internalType: 'enum ReleaseRegister.Status', + type: 'uint8', + }, + ], + name: 'setReleaseStatus', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ShortStrings +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const shortStringsAbi = [ + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Staking +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct StakingArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'nonpayable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingBalances +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingBalancesAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { + name: '_args', + internalType: 'struct StakingArgs', + type: 'tuple', + components: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'init', internalType: 'address', type: 'address' }, + { name: 'initCalldata', internalType: 'bytes', type: 'bytes' }, + { + name: 'contractResolver', + internalType: 'address', + type: 'address', + }, + { + name: 'env', + internalType: 'enum ContractResolver.Env', + type: 'uint8', + }, + ], + }, + ], + stateMutability: 'payable', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'FunctionNotFound', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { type: 'fallback', stateMutability: 'payable' }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingBalancesDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingBalancesDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'ActiveValidatorsCannotLeave' }, + { + type: 'error', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'AliasNotOwnedBySender', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'CannotRemoveAliasOfActiveValidator', + }, + { type: 'error', inputs: [], name: 'CannotStakeZero' }, + { type: 'error', inputs: [], name: 'CannotWithdrawZero' }, + { + type: 'error', + inputs: [{ name: 'aliasCount', internalType: 'uint256', type: 'uint256' }], + name: 'MaxAliasCountReached', + }, + { + type: 'error', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: 'OnlyStakingContract', + }, + { + type: 'error', + inputs: [ + { name: 'amountStaked', internalType: 'uint256', type: 'uint256' }, + { name: 'minimumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'StakeMustBeGreaterThanMinimumStake', + }, + { + type: 'error', + inputs: [ + { name: 'amountStaked', internalType: 'uint256', type: 'uint256' }, + { name: 'maximumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'StakeMustBeLessThanMaximumStake', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'StakerNotPermitted', + }, + { + type: 'error', + inputs: [ + { name: 'yourBalance', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestedWithdrawlAmount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'TryingToWithdrawMoreThanStaked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AliasAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AliasRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMaxAliasCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MaxAliasCountSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMaximumStake', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MaximumStakeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMinimumStake', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MinimumStakeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'PermittedStakerAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'PermittedStakerRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'permittedStakersOn', + internalType: 'bool', + type: 'bool', + indexed: false, + }, + ], + name: 'PermittedStakersOnChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ResolverContractAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'reward', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RewardPaid', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Staked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenRewardPerTokenPerEpochSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ValidatorNotRewardedBecauseAlias', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorRewarded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorTokensPenalized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrawn', + }, + { + type: 'function', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'addAlias', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'addPermittedStaker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'stakers', internalType: 'address[]', type: 'address[]' }], + name: 'addPermittedStakers', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'checkStakingAmounts', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getStakingAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getTokenAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'isPermittedStaker', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maximumStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'minimumStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'penalizeTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'permittedStakersOn', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'removeAlias', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'removePermittedStaker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'staker', internalType: 'address', type: 'address' }, + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + ], + name: 'restakePenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'rewardOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'rewardValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMaxAliasCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMaxAliasCount', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMaximumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMaximumStake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMinimumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMinimumStake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'permitted', internalType: 'bool', type: 'bool' }], + name: 'setPermittedStakersOn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'totalStaked', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + ], + name: 'transferPenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + name: 'withdrawPenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingBalancesFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingBalancesFacetAbi = [ + { type: 'error', inputs: [], name: 'ActiveValidatorsCannotLeave' }, + { + type: 'error', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'AliasNotOwnedBySender', + }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'CannotRemoveAliasOfActiveValidator', + }, + { type: 'error', inputs: [], name: 'CannotStakeZero' }, + { type: 'error', inputs: [], name: 'CannotWithdrawZero' }, + { + type: 'error', + inputs: [{ name: 'aliasCount', internalType: 'uint256', type: 'uint256' }], + name: 'MaxAliasCountReached', + }, + { + type: 'error', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: 'OnlyStakingContract', + }, + { + type: 'error', + inputs: [ + { name: 'amountStaked', internalType: 'uint256', type: 'uint256' }, + { name: 'minimumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'StakeMustBeGreaterThanMinimumStake', + }, + { + type: 'error', + inputs: [ + { name: 'amountStaked', internalType: 'uint256', type: 'uint256' }, + { name: 'maximumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'StakeMustBeLessThanMaximumStake', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'StakerNotPermitted', + }, + { + type: 'error', + inputs: [ + { name: 'yourBalance', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestedWithdrawlAmount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'TryingToWithdrawMoreThanStaked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AliasAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'AliasRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMaxAliasCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MaxAliasCountSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMaximumStake', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MaximumStakeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newMinimumStake', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'MinimumStakeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'PermittedStakerAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'PermittedStakerRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'permittedStakersOn', + internalType: 'bool', + type: 'bool', + indexed: false, + }, + ], + name: 'PermittedStakersOnChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ResolverContractAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'reward', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RewardPaid', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Staked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenRewardPerTokenPerEpochSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'aliasAccount', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ValidatorNotRewardedBecauseAlias', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorRewarded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorTokensPenalized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrawn', + }, + { + type: 'function', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'addAlias', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'addPermittedStaker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'stakers', internalType: 'address[]', type: 'address[]' }], + name: 'addPermittedStakers', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'checkStakingAmounts', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getStakingAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getTokenAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'isPermittedStaker', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'maximumStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'minimumStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'penalizeTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'permittedStakersOn', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'aliasAccount', internalType: 'address', type: 'address' }, + ], + name: 'removeAlias', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'removePermittedStaker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'staker', internalType: 'address', type: 'address' }, + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + ], + name: 'restakePenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'rewardOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'rewardValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMaxAliasCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMaxAliasCount', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMaximumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMaximumStake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newMinimumStake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setMinimumStake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'permitted', internalType: 'bool', type: 'bool' }], + name: 'setPermittedStakersOn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'totalStaked', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + ], + name: 'transferPenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'balance', internalType: 'uint256', type: 'uint256' }], + name: 'withdrawPenaltyTokens', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingDiamond +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingDiamondAbi = [ + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotAddFunctionToDiamondThatAlreadyExists', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotAddSelectorsToZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveFunctionThatDoesNotExist', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotRemoveImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionThatDoesNotExists', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet', + }, + { + type: 'error', + inputs: [ + { name: '_selectors', internalType: 'bytes4[]', type: 'bytes4[]' }, + ], + name: 'CannotReplaceFunctionsFromFacetWithZeroAddress', + }, + { + type: 'error', + inputs: [{ name: '_selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'CannotReplaceImmutableFunction', + }, + { + type: 'error', + inputs: [{ name: '_action', internalType: 'uint8', type: 'uint8' }], + name: 'IncorrectFacetCutAction', + }, + { + type: 'error', + inputs: [ + { + name: '_initializationContractAddress', + internalType: 'address', + type: 'address', + }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'InitializationFunctionReverted', + }, + { + type: 'error', + inputs: [ + { name: '_contractAddress', internalType: 'address', type: 'address' }, + { name: '_message', internalType: 'string', type: 'string' }, + ], + name: 'NoBytecodeAtAddress', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'NoSelectorsProvidedForFacetForCut', + }, + { + type: 'error', + inputs: [ + { name: '_user', internalType: 'address', type: 'address' }, + { name: '_contractOwner', internalType: 'address', type: 'address' }, + ], + name: 'NotContractOwner', + }, + { + type: 'error', + inputs: [ + { name: '_facetAddress', internalType: 'address', type: 'address' }, + ], + name: 'RemoveFacetAddressMustBeZeroAddress', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + indexed: false, + }, + { + name: '_init', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: '_calldata', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'DiamondCut', + }, + { + type: 'function', + inputs: [ + { + name: '_diamondCut', + internalType: 'struct IDiamond.FacetCut[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'action', + internalType: 'enum IDiamond.FacetCutAction', + type: 'uint8', + }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + { name: '_init', internalType: 'address', type: 'address' }, + { name: '_calldata', internalType: 'bytes', type: 'bytes' }, + ], + name: 'diamondCut', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_functionSelector', internalType: 'bytes4', type: 'bytes4' }, + ], + name: 'facetAddress', + outputs: [ + { name: 'facetAddress_', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facetAddresses', + outputs: [ + { name: 'facetAddresses_', internalType: 'address[]', type: 'address[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_facet', internalType: 'address', type: 'address' }], + name: 'facetFunctionSelectors', + outputs: [ + { + name: '_facetFunctionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'facets', + outputs: [ + { + name: 'facets_', + internalType: 'struct IDiamondLoupe.Facet[]', + type: 'tuple[]', + components: [ + { name: 'facetAddress', internalType: 'address', type: 'address' }, + { + name: 'functionSelectors', + internalType: 'bytes4[]', + type: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: 'owner_', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'ActiveValidatorsCannotLeave' }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [], + name: 'CannotKickBelowCurrentValidatorThreshold', + }, + { + type: 'error', + inputs: [ + { name: 'stakingAddress', internalType: 'address', type: 'address' }, + ], + name: 'CannotRejoinUntilNextEpochBecauseKicked', + }, + { + type: 'error', + inputs: [ + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'CannotReuseCommsKeys', + }, + { type: 'error', inputs: [], name: 'CannotStakeZero' }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'CannotVoteTwice', + }, + { type: 'error', inputs: [], name: 'CannotWithdrawZero' }, + { + type: 'error', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'CouldNotMapNodeAddressToStakerAddress', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInActiveOrUnlockedOrPausedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInActiveOrUnlockedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedOrReadyForNextEpochOrRestoreState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedOrReadyForNextEpochState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInReadyForNextEpochState', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'MustBeValidatorInNextEpochToKick', + }, + { + type: 'error', + inputs: [ + { name: 'currentTimestamp', internalType: 'uint256', type: 'uint256' }, + { name: 'epochEndTime', internalType: 'uint256', type: 'uint256' }, + { name: 'timeout', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NotEnoughTimeElapsedForTimeoutSinceLastEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'currentTimestamp', internalType: 'uint256', type: 'uint256' }, + { name: 'epochEndTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NotEnoughTimeElapsedSinceLastEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'validatorCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'minimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'NotEnoughValidatorsInNextEpoch', + }, + { + type: 'error', + inputs: [ + { + name: 'currentReadyValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'nextReadyValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'minimumValidatorCountToBeReady', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'NotEnoughValidatorsReadyForNextEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'currentEpochNumber', internalType: 'uint256', type: 'uint256' }, + { name: 'receivedEpochNumber', internalType: 'uint256', type: 'uint256' }, + ], + name: 'SignaledReadyForWrongEpochNumber', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'StakerNotPermitted', + }, + { + type: 'error', + inputs: [ + { name: 'yourBalance', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestedWithdrawlAmount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'TryingToWithdrawMoreThanStaked', + }, + { + type: 'error', + inputs: [ + { name: 'validator', internalType: 'address', type: 'address' }, + { + name: 'validatorsInNextEpoch', + internalType: 'address[]', + type: 'address[]', + }, + ], + name: 'ValidatorIsNotInNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newComplaintTolerance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newComplaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newKeyTypes', + internalType: 'uint256[]', + type: 'uint256[]', + indexed: false, + }, + { + name: 'newMinimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxTripleCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMinTripleCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newPeerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ConfigSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochEndTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochEndTimeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochLength', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochLengthSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochTimeout', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochTimeoutSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'reason', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newKickPenaltyPercent', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'KickPenaltyPercentSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'epochNumber', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ReadyForNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'token', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Recovered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RequestToJoin', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RequestToLeave', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverContractAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ResolverContractAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newDuration', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RewardsDurationUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newStakingTokenAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'StakingTokenSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newState', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + indexed: false, + }, + ], + name: 'StateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amountBurned', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorKickedFromNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ValidatorRejoinedNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'reporter', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'reason', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'data', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'VotedToKickValidatorInNextEpoch', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + ], + name: 'adminKickValidatorInNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'adminRejoinValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'adminResetEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'amountToPenalize', internalType: 'uint256', type: 'uint256' }, + ], + name: 'adminSlashValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'advanceEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'exit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'reason', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'kickValidatorInNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'lockValidatorsForNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'requestToJoin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'requestToLeave', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'requestToLeaveAsNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newComplaintTolerance', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newComplaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'newKeyTypes', internalType: 'uint256[]', type: 'uint256[]' }, + { + name: 'newMinimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newMaxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'newMaxTripleCount', internalType: 'uint256', type: 'uint256' }, + { name: 'newMinTripleCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'newPeerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newMaxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setConfig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochEndTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochEndTime', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochLength', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newState', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'setEpochState', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochTimeout', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochTimeout', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setIpPortNodeAddressAndCommunicationPubKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'reason', internalType: 'uint256', type: 'uint256' }, + { + name: 'newKickPenaltyPercent', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setKickPenaltyPercent', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'epochNumber', internalType: 'uint256', type: 'uint256' }], + name: 'signalReadyForNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stakeAndJoin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'index', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'VersionRequirementsUpdated', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'checkVersion', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxVersion', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxVersionString', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMinVersion', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMinVersionString', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'setMaxVersion', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'setMinVersion', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'config', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Config', + type: 'tuple', + components: [ + { + name: 'tokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'complaintTolerance', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'complaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'keyTypes', internalType: 'uint256[]', type: 'uint256[]' }, + { + name: 'minimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'maxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'maxTripleCount', internalType: 'uint256', type: 'uint256' }, + { name: 'minTripleCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'peerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'maxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'countOfCurrentValidatorsReadyForNextEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'countOfNextValidatorsReadyForNextEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'currentValidatorCountForConsensus', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'epoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Epoch', + type: 'tuple', + components: [ + { name: 'epochLength', internalType: 'uint256', type: 'uint256' }, + { name: 'number', internalType: 'uint256', type: 'uint256' }, + { name: 'endTime', internalType: 'uint256', type: 'uint256' }, + { name: 'retries', internalType: 'uint256', type: 'uint256' }, + { name: 'timeout', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getKeyTypes', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getKickedValidators', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addresses', internalType: 'address[]', type: 'address[]' }, + ], + name: 'getNodeStakerAddressMappings', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.AddressMapping[]', + type: 'tuple[]', + components: [ + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakingBalancesAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getTokenAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInCurrentEpoch', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInCurrentEpochLength', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInNextEpoch', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addresses', internalType: 'address[]', type: 'address[]' }, + ], + name: 'getValidatorsStructs', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsStructsInCurrentEpoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsStructsInNextEpoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epochNumber', internalType: 'uint256', type: 'uint256' }, + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'voterStakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'getVotingStatusToKickValidator', + outputs: [ + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'bool', type: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'isActiveValidator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'isActiveValidatorByNodeAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isReadyForNextEpoch', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'reason', internalType: 'uint256', type: 'uint256' }], + name: 'kickPenaltyPercentByReason', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'nextValidatorCountForConsensus', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'nodeAddressToStakerAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'readyForNextEpoch', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'shouldKickValidator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'state', + outputs: [ + { + name: '', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'validators', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator', + type: 'tuple', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingFacetAbi = [ + { type: 'error', inputs: [], name: 'ActiveValidatorsCannotLeave' }, + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'error', + inputs: [], + name: 'CannotKickBelowCurrentValidatorThreshold', + }, + { + type: 'error', + inputs: [ + { name: 'stakingAddress', internalType: 'address', type: 'address' }, + ], + name: 'CannotRejoinUntilNextEpochBecauseKicked', + }, + { + type: 'error', + inputs: [ + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'CannotReuseCommsKeys', + }, + { type: 'error', inputs: [], name: 'CannotStakeZero' }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'CannotVoteTwice', + }, + { type: 'error', inputs: [], name: 'CannotWithdrawZero' }, + { + type: 'error', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'CouldNotMapNodeAddressToStakerAddress', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInActiveOrUnlockedOrPausedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInActiveOrUnlockedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedOrReadyForNextEpochOrRestoreState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedOrReadyForNextEpochState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInNextValidatorSetLockedState', + }, + { + type: 'error', + inputs: [ + { + name: 'state', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'MustBeInReadyForNextEpochState', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'MustBeValidatorInNextEpochToKick', + }, + { + type: 'error', + inputs: [ + { name: 'currentTimestamp', internalType: 'uint256', type: 'uint256' }, + { name: 'epochEndTime', internalType: 'uint256', type: 'uint256' }, + { name: 'timeout', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NotEnoughTimeElapsedForTimeoutSinceLastEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'currentTimestamp', internalType: 'uint256', type: 'uint256' }, + { name: 'epochEndTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NotEnoughTimeElapsedSinceLastEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'validatorCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'minimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'NotEnoughValidatorsInNextEpoch', + }, + { + type: 'error', + inputs: [ + { + name: 'currentReadyValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'nextReadyValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'minimumValidatorCountToBeReady', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'NotEnoughValidatorsReadyForNextEpoch', + }, + { + type: 'error', + inputs: [ + { name: 'currentEpochNumber', internalType: 'uint256', type: 'uint256' }, + { name: 'receivedEpochNumber', internalType: 'uint256', type: 'uint256' }, + ], + name: 'SignaledReadyForWrongEpochNumber', + }, + { + type: 'error', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'StakerNotPermitted', + }, + { + type: 'error', + inputs: [ + { name: 'yourBalance', internalType: 'uint256', type: 'uint256' }, + { + name: 'requestedWithdrawlAmount', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'TryingToWithdrawMoreThanStaked', + }, + { + type: 'error', + inputs: [ + { name: 'validator', internalType: 'address', type: 'address' }, + { + name: 'validatorsInNextEpoch', + internalType: 'address[]', + type: 'address[]', + }, + ], + name: 'ValidatorIsNotInNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newComplaintTolerance', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newComplaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newKeyTypes', + internalType: 'uint256[]', + type: 'uint256[]', + indexed: false, + }, + { + name: 'newMinimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxTripleCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMinTripleCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newPeerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newMaxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ConfigSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochEndTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochEndTimeSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochLength', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochLengthSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newEpochTimeout', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'EpochTimeoutSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'reason', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newKickPenaltyPercent', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'KickPenaltyPercentSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'epochNumber', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ReadyForNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'token', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Recovered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RequestToJoin', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RequestToLeave', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newResolverContractAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ResolverContractAddressSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newDuration', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RewardsDurationUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newStakingTokenAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'StakingTokenSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newState', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + indexed: false, + }, + ], + name: 'StateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'amountBurned', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ValidatorKickedFromNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'staker', + internalType: 'address', + type: 'address', + indexed: false, + }, + ], + name: 'ValidatorRejoinedNextEpoch', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'reporter', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'reason', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'data', internalType: 'bytes', type: 'bytes', indexed: false }, + ], + name: 'VotedToKickValidatorInNextEpoch', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + ], + name: 'adminKickValidatorInNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'staker', internalType: 'address', type: 'address' }], + name: 'adminRejoinValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'adminResetEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'amountToPenalize', internalType: 'uint256', type: 'uint256' }, + ], + name: 'adminSlashValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'advanceEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'exit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'reason', internalType: 'uint256', type: 'uint256' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'kickValidatorInNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'lockValidatorsForNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'requestToJoin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'requestToLeave', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'requestToLeaveAsNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newTokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newComplaintTolerance', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newComplaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'newKeyTypes', internalType: 'uint256[]', type: 'uint256[]' }, + { + name: 'newMinimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newMaxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'newMaxTripleCount', internalType: 'uint256', type: 'uint256' }, + { name: 'newMinTripleCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'newPeerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'newMaxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setConfig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newResolverAddress', internalType: 'address', type: 'address' }, + ], + name: 'setContractResolver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochEndTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochEndTime', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochLength', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newState', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + name: 'setEpochState', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newEpochTimeout', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setEpochTimeout', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setIpPortNodeAddressAndCommunicationPubKeys', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'reason', internalType: 'uint256', type: 'uint256' }, + { + name: 'newKickPenaltyPercent', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'setKickPenaltyPercent', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'epochNumber', internalType: 'uint256', type: 'uint256' }], + name: 'signalReadyForNextEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stakeAndJoin', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingVersionFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingVersionFacetAbi = [ + { type: 'error', inputs: [], name: 'CallerNotOwner' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'index', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, + ], + name: 'VersionRequirementsUpdated', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'checkVersion', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxVersion', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxVersionString', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMinVersion', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMinVersionString', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'setMaxVersion', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'version', + internalType: 'struct LibStakingStorage.Version', + type: 'tuple', + components: [ + { name: 'major', internalType: 'uint256', type: 'uint256' }, + { name: 'minor', internalType: 'uint256', type: 'uint256' }, + { name: 'patch', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'setMinVersion', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// StakingViewsFacet +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const stakingViewsFacetAbi = [ + { + type: 'function', + inputs: [], + name: 'config', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Config', + type: 'tuple', + components: [ + { + name: 'tokenRewardPerTokenPerEpoch', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'complaintTolerance', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'complaintIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'keyTypes', internalType: 'uint256[]', type: 'uint256[]' }, + { + name: 'minimumValidatorCount', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'maxConcurrentRequests', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'maxTripleCount', internalType: 'uint256', type: 'uint256' }, + { name: 'minTripleCount', internalType: 'uint256', type: 'uint256' }, + { + name: 'peerCheckingIntervalSecs', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'maxTripleConcurrency', + internalType: 'uint256', + type: 'uint256', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'contractResolver', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'countOfCurrentValidatorsReadyForNextEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'countOfNextValidatorsReadyForNextEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'currentValidatorCountForConsensus', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'epoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Epoch', + type: 'tuple', + components: [ + { name: 'epochLength', internalType: 'uint256', type: 'uint256' }, + { name: 'number', internalType: 'uint256', type: 'uint256' }, + { name: 'endTime', internalType: 'uint256', type: 'uint256' }, + { name: 'retries', internalType: 'uint256', type: 'uint256' }, + { name: 'timeout', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getKeyTypes', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getKickedValidators', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addresses', internalType: 'address[]', type: 'address[]' }, + ], + name: 'getNodeStakerAddressMappings', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.AddressMapping[]', + type: 'tuple[]', + components: [ + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getStakingBalancesAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getTokenAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInCurrentEpoch', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInCurrentEpochLength', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsInNextEpoch', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addresses', internalType: 'address[]', type: 'address[]' }, + ], + name: 'getValidatorsStructs', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsStructsInCurrentEpoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getValidatorsStructsInNextEpoch', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator[]', + type: 'tuple[]', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epochNumber', internalType: 'uint256', type: 'uint256' }, + { + name: 'validatorStakerAddress', + internalType: 'address', + type: 'address', + }, + { name: 'voterStakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'getVotingStatusToKickValidator', + outputs: [ + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'bool', type: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'isActiveValidator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'isActiveValidatorByNodeAddress', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'isReadyForNextEpoch', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'reason', internalType: 'uint256', type: 'uint256' }], + name: 'kickPenaltyPercentByReason', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'nextValidatorCountForConsensus', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'nodeAddressToStakerAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'readyForNextEpoch', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'shouldKickValidator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'state', + outputs: [ + { + name: '', + internalType: 'enum LibStakingStorage.States', + type: 'uint8', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'stakerAddress', internalType: 'address', type: 'address' }, + ], + name: 'validators', + outputs: [ + { + name: '', + internalType: 'struct LibStakingStorage.Validator', + type: 'tuple', + components: [ + { name: 'ip', internalType: 'uint32', type: 'uint32' }, + { name: 'ipv6', internalType: 'uint128', type: 'uint128' }, + { name: 'port', internalType: 'uint32', type: 'uint32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'reward', internalType: 'uint256', type: 'uint256' }, + { name: 'senderPubKey', internalType: 'uint256', type: 'uint256' }, + { name: 'receiverPubKey', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, +] as const; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// WLIT +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const wlitAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'src', internalType: 'address', type: 'address', indexed: true }, + { name: 'guy', internalType: 'address', type: 'address', indexed: true }, + { name: 'wad', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'dst', internalType: 'address', type: 'address', indexed: true }, + { name: 'wad', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Deposit', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'src', internalType: 'address', type: 'address', indexed: true }, + { name: 'dst', internalType: 'address', type: 'address', indexed: true }, + { name: 'wad', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'src', internalType: 'address', type: 'address', indexed: true }, + { name: 'wad', internalType: 'uint256', type: 'uint256', indexed: false }, + ], + name: 'Withdrawal', + }, + { type: 'fallback', stateMutability: 'payable' }, + { + type: 'function', + inputs: [ + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'guy', internalType: 'address', type: 'address' }, + { name: 'wad', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'deposit', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'dst', internalType: 'address', type: 'address' }, + { name: 'wad', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'src', internalType: 'address', type: 'address' }, + { name: 'dst', internalType: 'address', type: 'address' }, + { name: 'wad', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'wad', internalType: 'uint256', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'receive', stateMutability: 'payable' }, +] as const; diff --git a/ci/anvil/Dockerfile b/ci/anvil/Dockerfile new file mode 100644 index 0000000..74106b6 --- /dev/null +++ b/ci/anvil/Dockerfile @@ -0,0 +1,14 @@ +# Use the latest foundry image +FROM ghcr.io/lit-protocol/foundry + +COPY ./start_anvil.sh ./start_anvil.sh +RUN chmod +x ./start_anvil.sh + +EXPOSE 8545 + +# Define service as up when anvil is listening. +HEALTHCHECK --interval=5s --timeout=3s \ + CMD grep 'Listening on 0.0.0.0:8545' anvil.log + +# Start the anvil server with 10 accounts +ENTRYPOINT ["./start_anvil.sh"] \ No newline at end of file diff --git a/ci/anvil/README.md b/ci/anvil/README.md new file mode 100644 index 0000000..501ec1f --- /dev/null +++ b/ci/anvil/README.md @@ -0,0 +1,17 @@ +# Build + +```bash +docker build . -t anvil +``` + +# Run + +```bash +docker run anvil +``` + +# Debug + +```bash +docker exec -it /bin/sh +``` diff --git a/ci/anvil/start_anvil.sh b/ci/anvil/start_anvil.sh new file mode 100644 index 0000000..aaf6e85 --- /dev/null +++ b/ci/anvil/start_anvil.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +anvil -a 10 --host 0.0.0.0 > anvil.log 2>&1 \ No newline at end of file diff --git a/contracts/AccessControlConditions.sol b/contracts/AccessControlConditions.sol deleted file mode 100644 index c8efaf3..0000000 --- a/contracts/AccessControlConditions.sol +++ /dev/null @@ -1,127 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; - -import "hardhat/console.sol"; - -contract AccessControlConditions is Ownable, ReentrancyGuard { - /* ========== STRUCTS ========== */ - struct StoredCondition { - uint256 value; - uint256 securityHash; - uint256 chainId; - bool permanent; - address creator; - } - - /* ========== STATE VARIABLES ========== */ - - mapping(uint256 => StoredCondition) public storedConditions; - address public signer; - - /* ========== CONSTRUCTOR ========== */ - constructor() { - signer = msg.sender; - } - - /* ========== VIEWS ========== */ - - function getCondition(uint256 key) - external - view - returns (StoredCondition memory) - { - return storedConditions[key]; - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - function storeCondition( - uint256 key, - uint256 value, - uint256 securityHash, - uint256 chainId, - bool permanent - ) external nonReentrant { - _storeCondition( - key, - value, - securityHash, - chainId, - permanent, - msg.sender - ); - } - - function storeConditionWithSigner( - uint256 key, - uint256 value, - uint256 securityHash, - uint256 chainId, - bool permanent, - address creatorAddress - ) external nonReentrant { - require( - msg.sender == signer, - "Only signer can call storeConditionsWithSigner." - ); - _storeCondition( - key, - value, - securityHash, - chainId, - permanent, - creatorAddress - ); - } - - function setSigner(address newSigner) public onlyOwner { - signer = newSigner; - } - - /* ========== PRIVATE FUNCTIONS ========== */ - - function _storeCondition( - uint256 key, - uint256 value, - uint256 securityHash, - uint256 chainId, - bool permanent, - address creatorAddress - ) private { - require(key != 0, "Key must not be zero"); - if (storedConditions[key].creator != address(0)) { - // this is an update - require( - storedConditions[key].creator == creatorAddress, - "Only the condition creator can update it" - ); - require( - storedConditions[key].permanent == false, - "This condition was stored with the Permanent flag and cannot be updated" - ); - require(msg.sender != signer, "Signer cannot update conditions"); - } - storedConditions[key] = StoredCondition( - value, - securityHash, - chainId, - permanent, - creatorAddress - ); - - emit ConditionStored(key, value, chainId, permanent, creatorAddress); - } - - /* ========== EVENTS ========== */ - - event ConditionStored( - uint256 indexed key, - uint256 value, - uint256 chainId, - bool permanent, - address creator - ); -} diff --git a/contracts/ConditionValidations.sol b/contracts/ConditionValidations.sol deleted file mode 100644 index 30e2a45..0000000 --- a/contracts/ConditionValidations.sol +++ /dev/null @@ -1,124 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; - -import "hardhat/console.sol"; - -/// @title Lit Protocol Validation Record -/// -/// @dev This is the contract for recording cross chain validations. -/// -/// Briefly, this contract is used to record the validation of a transaction - -/* -Todos -- conditions are mutative by nature, and only exist at a point in time. So do we need to be able to update them, or just keep a point in time record? - - if we keep a running history, AND we want to be able to reference them by condition hash, we may end up with an array of arrays ... or other more complex structure. - - alternatively, we could just map the most recent condition, storing historical conditions in a seperate structure (ie, move them -> however this risks significant gaps, based on updates. - It's also identical tot he "emit", but with no guarantees of emitted data being complete.) -- need to be able to update public keys / owners; currently this is a single owner contract, and we can't update the owner. -*/ - -contract ConditionValidations is ReentrancyGuard { - /* ========== STRUCTS ========== */ - struct ValidatedCondition { - uint256 chainId; - uint256 timestamp; - address creator; - } - - /* ========== STATE VARIABLES ========== */ - mapping(bytes32 => ValidatedCondition) public validatedConditions; - mapping(address => bool) public validAddresses; - - /* ========== CONSTRUCTOR ========== */ - - // constructor(bytes memory _publicKey) { - // require(_publicKey.length == 64); - // address addrFromPublicKey = address( - // bytes20(uint160(uint(keccak256(_publicKey)))) - // ); - - // validAddresses[addrFromPublicKey] = true; - // } - - constructor(address _ownerAddress) { - validAddresses[_ownerAddress] = true; - } - - /* ========== VIEWS ========== */ - - function getValidatedCondition(bytes32 conditionHashKey) - external - view - returns (ValidatedCondition memory) - { - // check if key exists in validatedConditions - if (validatedConditions[conditionHashKey].timestamp != 0) { - return validatedConditions[conditionHashKey]; - } else { - return ValidatedCondition(0, 0, address(0)); - } - } - - function verifySignature(bytes32 conditionHash, bytes memory signature) - external - view - returns (bool) - { - address sigAddress = ECDSA.recover(conditionHash, signature); - - return validAddresses[sigAddress]; - } - - function testPubKeyToAddress(bytes memory _publicKey) - external - pure - returns (address) - { - //require(_publicKey.length == 64); - address addrFromPublicKey = address( - uint160(uint256(keccak256(_publicKey))) - ); - - return addrFromPublicKey; - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - function storeValidatedCondition( - uint256 chainId, - bytes32 conditionHash, - bytes memory signature - ) external nonReentrant { - // check if the signature is valid - address sigAddress = ECDSA.recover(conditionHash, signature); - - require( - validAddresses[sigAddress], - "Signature doesn't match any LIT key for the given hashed condition" - ); - - validatedConditions[conditionHash] = ValidatedCondition( - chainId, - block.timestamp, - msg.sender - ); - emit ValidationStored( - conditionHash, - chainId, - block.timestamp, - msg.sender - ); - } - - /* ========== EVENTS ========== */ - - event ValidationStored( - bytes32 indexed conditionHash, - uint256 chainId, - uint256 timestamp, - address creator - ); -} diff --git a/contracts/PKPHelper.sol b/contracts/PKPHelper.sol deleted file mode 100644 index 95e0070..0000000 --- a/contracts/PKPHelper.sol +++ /dev/null @@ -1,179 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { PKPPermissions } from "./PKPPermissions.sol"; -import { PKPNFT } from "./PKPNFT.sol"; -import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; -import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; - -// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn - -/// @title Programmable Keypair NFT -/// -/// @dev This is the contract for the PKP NFTs -/// -/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. -/// The owner can also grant signing permissions to other eth addresses -/// or lit actions -contract PKPHelper is Ownable, IERC721Receiver { - /* ========== STATE VARIABLES ========== */ - - PKPNFT public pkpNFT; - PKPPermissions public pkpPermissions; - - /* ========== CONSTRUCTOR ========== */ - constructor(address _pkpNft, address _pkpPermissions) { - pkpNFT = PKPNFT(_pkpNft); - pkpPermissions = PKPPermissions(_pkpPermissions); - } - - /* ========== VIEWS ========== */ - - /* ========== MUTATIVE FUNCTIONS ========== */ - - function mintNextAndAddAuthMethods( - uint256 keyType, - uint256[] memory permittedAuthMethodTypes, - bytes[] memory permittedAuthMethodIds, - bytes[] memory permittedAuthMethodPubkeys, - uint256[][] memory permittedAuthMethodScopes, - bool addPkpEthAddressAsPermittedAddress, - bool sendPkpToItself - ) public payable returns (uint256) { - return - mintNextAndAddAuthMethodsWithTypes( - keyType, - new bytes[](0), // permitted ipfs CIDs - new uint256[][](0), // permitted ipfs CIDs scopes - new address[](0), // permitted addresses - new uint256[][](0), // permitted addresses scopes - permittedAuthMethodTypes, - permittedAuthMethodIds, - permittedAuthMethodPubkeys, - permittedAuthMethodScopes, - addPkpEthAddressAsPermittedAddress, - sendPkpToItself - ); - } - - function mintNextAndAddAuthMethodsWithTypes( - uint256 keyType, - bytes[] memory permittedIpfsCIDs, - uint256[][] memory permittedIpfsCIDScopes, - address[] memory permittedAddresses, - uint256[][] memory permittedAddressScopes, - uint256[] memory permittedAuthMethodTypes, - bytes[] memory permittedAuthMethodIds, - bytes[] memory permittedAuthMethodPubkeys, - uint256[][] memory permittedAuthMethodScopes, - bool addPkpEthAddressAsPermittedAddress, - bool sendPkpToItself - ) public payable returns (uint256) { - // mint the nft and forward the funds - uint256 tokenId = pkpNFT.mintNext{ value: msg.value }(keyType); - - // sanity checking array lengths - require( - permittedIpfsCIDs.length == permittedIpfsCIDScopes.length, - "PKPHelper: ipfs cid and scope array lengths must match" - ); - require( - permittedAddresses.length == permittedAddressScopes.length, - "PKPHelper: address and scope array lengths must match" - ); - require( - permittedAuthMethodTypes.length == permittedAuthMethodIds.length, - "PKPHelper: auth method type and id array lengths must match" - ); - require( - permittedAuthMethodTypes.length == - permittedAuthMethodPubkeys.length, - "PKPHelper: auth method type and pubkey array lengths must match" - ); - require( - permittedAuthMethodTypes.length == permittedAuthMethodScopes.length, - "PKPHelper: auth method type and scopes array lengths must match" - ); - - // permit the action - if (permittedIpfsCIDs.length != 0) { - for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) { - pkpPermissions.addPermittedAction( - tokenId, - permittedIpfsCIDs[i], - permittedIpfsCIDScopes[i] - ); - } - } - - // permit the address - if (permittedAddresses.length != 0) { - for (uint256 i = 0; i < permittedAddresses.length; i++) { - pkpPermissions.addPermittedAddress( - tokenId, - permittedAddresses[i], - permittedAddressScopes[i] - ); - } - } - - // permit the auth method - if (permittedAuthMethodTypes.length != 0) { - for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) { - pkpPermissions.addPermittedAuthMethod( - tokenId, - PKPPermissions.AuthMethod( - permittedAuthMethodTypes[i], - permittedAuthMethodIds[i], - permittedAuthMethodPubkeys[i] - ), - permittedAuthMethodScopes[i] - ); - } - } - - address pkpEthAddress = pkpPermissions.getEthAddress(tokenId); - - // add the pkp eth address as a permitted address - if (addPkpEthAddressAsPermittedAddress) { - pkpPermissions.addPermittedAddress( - tokenId, - pkpEthAddress, - new uint256[](0) - ); - } - - if (sendPkpToItself) { - pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId); - } else { - pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId); - } - - return tokenId; - } - - function setPkpNftAddress(address newPkpNftAddress) public onlyOwner { - pkpNFT = PKPNFT(newPkpNftAddress); - } - - function setPkpPermissionsAddress( - address newPkpPermissionsAddress - ) public onlyOwner { - pkpPermissions = PKPPermissions(newPkpPermissionsAddress); - } - - function onERC721Received( - address /* operator */, - address /* from */, - uint256 /* tokenId */, - bytes calldata /* data */ - ) external view override returns (bytes4) { - // only accept transfers from the pkpNft contract - require( - msg.sender == address(pkpNFT), - "PKPHelper: only accepts transfers from the PKPNFT contract" - ); - return this.onERC721Received.selector; - } -} diff --git a/contracts/PKPNFT.sol b/contracts/PKPNFT.sol deleted file mode 100644 index 0af7157..0000000 --- a/contracts/PKPNFT.sol +++ /dev/null @@ -1,325 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { PubkeyRouter } from "./PubkeyRouter.sol"; -import { PKPPermissions } from "./PKPPermissions.sol"; -import { PKPNFTMetadata } from "./PKPNFTMetadata.sol"; -import { ERC721Burnable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; -import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; -import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; - -import "hardhat/console.sol"; - -// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn - -/// @title Programmable Keypair NFT -/// -/// @dev This is the contract for the PKP NFTs -/// -/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. -/// The owner can also grant signing permissions to other eth addresses -/// or lit actions -contract PKPNFT is - ERC721("Programmable Keypair", "PKP"), - Ownable, - ERC721Burnable, - ERC721Enumerable, - ReentrancyGuard -{ - /* ========== STATE VARIABLES ========== */ - - PubkeyRouter public router; - PKPPermissions public pkpPermissions; - PKPNFTMetadata public pkpNftMetadata; - uint256 public mintCost; - address public freeMintSigner; - - // maps keytype to array of unminted routed token ids - mapping(uint256 => uint256[]) public unmintedRoutedTokenIds; - - mapping(uint256 => bool) public redeemedFreeMintIds; - - /* ========== CONSTRUCTOR ========== */ - constructor() { - mintCost = 1; // 1 wei aka 0.000000000000000001 eth - freeMintSigner = msg.sender; - } - - /* ========== VIEWS ========== */ - - /// get the eth address for the keypair, as long as it's an ecdsa keypair - function getEthAddress(uint256 tokenId) public view returns (address) { - return router.getEthAddress(tokenId); - } - - /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress - function getPubkey(uint256 tokenId) public view returns (bytes memory) { - return router.getPubkey(tokenId); - } - - /// throws if the sig is bad or msg doesn't match - function freeMintSigTest( - uint256 freeMintId, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public view { - bytes32 expectedHash = prefixed( - keccak256(abi.encodePacked(address(this), freeMintId)) - ); - require( - expectedHash == msgHash, - "The msgHash is not a hash of the tokenId. Explain yourself!" - ); - - // make sure it was actually signed by freeMintSigner - address recovered = ecrecover(msgHash, v, r, s); - require( - recovered == freeMintSigner, - "This freeMint was not signed by freeMintSigner. How embarassing." - ); - - // prevent reuse - require( - redeemedFreeMintIds[freeMintId] == false, - "This free mint ID has already been redeemed" - ); - } - - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) { - return - interfaceId == type(IERC721Enumerable).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - interfaceId == type(IERC721).interfaceId; - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override(ERC721, ERC721Enumerable) { - ERC721Enumerable._beforeTokenTransfer(from, to, tokenId); - } - - function tokenURI( - uint256 tokenId - ) public view override returns (string memory) { - console.log("getting token uri"); - bytes memory pubKey = router.getPubkey(tokenId); - console.log("got pubkey, getting eth address"); - address ethAddress = router.getEthAddress(tokenId); - console.log("calling tokenURI"); - - return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress); - } - - function getUnmintedRoutedTokenIdCount( - uint256 keyType - ) public view returns (uint256) { - return unmintedRoutedTokenIds[keyType].length; - } - - // Builds a prefixed hash to mimic the behavior of eth_sign. - function prefixed(bytes32 hash) public pure returns (bytes32) { - return - keccak256( - abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) - ); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - function mintNext(uint256 keyType) public payable returns (uint256) { - require(msg.value == mintCost, "You must pay exactly mint cost"); - uint256 tokenId = _getNextTokenIdToMint(keyType); - _mintWithoutValueCheck(tokenId, msg.sender); - return tokenId; - } - - function mintGrantAndBurnNext( - uint256 keyType, - bytes memory ipfsCID - ) public payable returns (uint256) { - require(msg.value == mintCost, "You must pay exactly mint cost"); - uint256 tokenId = _getNextTokenIdToMint(keyType); - _mintWithoutValueCheck(tokenId, address(this)); - pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0)); - _burn(tokenId); - return tokenId; - } - - function freeMintNext( - uint256 keyType, - uint256 freeMintId, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public returns (uint256) { - uint256 tokenId = _getNextTokenIdToMint(keyType); - freeMint(freeMintId, tokenId, msgHash, v, r, s); - return tokenId; - } - - function freeMintGrantAndBurnNext( - uint256 keyType, - uint256 freeMintId, - bytes memory ipfsCID, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public returns (uint256) { - uint256 tokenId = _getNextTokenIdToMint(keyType); - freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s); - return tokenId; - } - - /// create a valid token for a given public key. - function mintSpecific(uint256 tokenId) public onlyOwner { - _mintWithoutValueCheck(tokenId, msg.sender); - } - - /// mint a PKP, grant access to a Lit Action, and then burn the PKP - /// this happens in a single txn, so it's provable that only that lit action - /// has ever had access to use the PKP. - /// this is useful in the context of something like a "prime number certification lit action" - /// where you could just trust the sig that a number is prime. - /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the - /// PKP to make it looks like only the Lit Action can use it. - function mintGrantAndBurnSpecific( - uint256 tokenId, - bytes memory ipfsCID - ) public onlyOwner { - _mintWithoutValueCheck(tokenId, address(this)); - pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0)); - _burn(tokenId); - } - - function freeMint( - uint256 freeMintId, - uint256 tokenId, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - // this will panic if the sig is bad - freeMintSigTest(freeMintId, msgHash, v, r, s); - _mintWithoutValueCheck(tokenId, msg.sender); - redeemedFreeMintIds[freeMintId] = true; - } - - function freeMintGrantAndBurn( - uint256 freeMintId, - uint256 tokenId, - bytes memory ipfsCID, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - // this will panic if the sig is bad - freeMintSigTest(freeMintId, msgHash, v, r, s); - _mintWithoutValueCheck(tokenId, address(this)); - redeemedFreeMintIds[freeMintId] = true; - pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0)); - _burn(tokenId); - } - - function _mintWithoutValueCheck(uint256 tokenId, address to) internal { - require(router.isRouted(tokenId), "This PKP has not been routed yet"); - - if (to == address(this)) { - // permit unsafe transfer only to this contract, because it's going to be burned - _mint(to, tokenId); - } else { - _safeMint(to, tokenId); - } - emit PKPMinted(tokenId, getPubkey(tokenId)); - } - - /// Take a tokenId off the stack - function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) { - require( - unmintedRoutedTokenIds[keyType].length > 0, - "There are no unminted routed token ids to mint" - ); - uint256 tokenId = unmintedRoutedTokenIds[keyType][ - unmintedRoutedTokenIds[keyType].length - 1 - ]; - - unmintedRoutedTokenIds[keyType].pop(); - - return tokenId; - } - - function setRouterAddress(address routerAddress) public onlyOwner { - router = PubkeyRouter(routerAddress); - emit RouterAddressSet(routerAddress); - } - - function setPkpNftMetadataAddress( - address pkpNftMetadataAddress - ) public onlyOwner { - pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress); - emit PkpNftMetadataAddressSet(pkpNftMetadataAddress); - } - - function setPkpPermissionsAddress( - address pkpPermissionsAddress - ) public onlyOwner { - pkpPermissions = PKPPermissions(pkpPermissionsAddress); - emit PkpPermissionsAddressSet(pkpPermissionsAddress); - } - - function setMintCost(uint256 newMintCost) public onlyOwner { - mintCost = newMintCost; - emit MintCostSet(newMintCost); - } - - function setFreeMintSigner(address newFreeMintSigner) public onlyOwner { - freeMintSigner = newFreeMintSigner; - emit FreeMintSignerSet(newFreeMintSigner); - } - - function withdraw() public onlyOwner nonReentrant { - uint256 withdrawAmount = address(this).balance; - (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); - require(sent); - emit Withdrew(withdrawAmount); - } - - /// Push a tokenId onto the stack - function pkpRouted(uint256 tokenId, uint256 keyType) public { - require( - msg.sender == address(router), - "Only the routing contract can call this function" - ); - unmintedRoutedTokenIds[keyType].push(tokenId); - emit PkpRouted(tokenId, keyType); - } - - /* ========== EVENTS ========== */ - - event RouterAddressSet(address indexed routerAddress); - event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress); - event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress); - event MintCostSet(uint256 newMintCost); - event FreeMintSignerSet(address indexed newFreeMintSigner); - event Withdrew(uint256 amount); - event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType); - event PKPMinted(uint256 indexed tokenId, bytes pubkey); -} diff --git a/contracts/PKPNFTMetadata.sol b/contracts/PKPNFTMetadata.sol deleted file mode 100644 index e2568b7..0000000 --- a/contracts/PKPNFTMetadata.sol +++ /dev/null @@ -1,83 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; - -import "hardhat/console.sol"; - -/// @title Programmable Keypair NFT Metadata -/// -/// @dev This is the contract for the PKP NFTs -/// -/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. -/// The owner can also grant signing permissions to other eth addresses -/// or lit actions -contract PKPNFTMetadata { - using Strings for uint256; - - /* ========== STATE VARIABLES ========== */ - - /* ========== CONSTRUCTOR ========== */ - constructor() {} - - /* ========== VIEWS ========== */ - - function bytesToHex(bytes memory buffer) - public - pure - returns (string memory) - { - // Fixed buffer size for hexadecimal convertion - bytes memory converted = new bytes(buffer.length * 2); - - bytes memory _base = "0123456789abcdef"; - - for (uint256 i = 0; i < buffer.length; i++) { - converted[i * 2] = _base[uint8(buffer[i]) / _base.length]; - converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length]; - } - - return string(abi.encodePacked("0x", converted)); - } - - function tokenURI( - uint256 tokenId, - bytes memory pubKey, - address ethAddress - ) public pure returns (string memory) { - string - memory svgData = ""; - - string memory pubkeyStr = bytesToHex(pubKey); - // console.log("pubkeyStr"); - // console.log(pubkeyStr); - - string memory ethAddressStr = Strings.toHexString(ethAddress); - // console.log("ethAddressStr"); - // console.log(ethAddressStr); - - string memory tokenIdStr = Strings.toString(tokenId); - - string memory json = Base64.encode( - bytes( - string( - abi.encodePacked( - '{"name": "Lit PKP #', - tokenIdStr, - '", "description": "This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP", "image_data": "', - bytes(svgData), - '","attributes": [{"trait_type": "Public Key", "value": "', - pubkeyStr, - '"}, {"trait_type": "ETH Wallet Address", "value": "', - ethAddressStr, - '"}, {"trait_type": "Token ID", "value": "', - tokenIdStr, - '"}]}' - ) - ) - ) - ); - return string(abi.encodePacked("data:application/json;base64,", json)); - } -} diff --git a/contracts/PubkeyRouter.sol b/contracts/PubkeyRouter.sol deleted file mode 100644 index c8bda25..0000000 --- a/contracts/PubkeyRouter.sol +++ /dev/null @@ -1,238 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import { PKPNFT } from "./PKPNFT.sol"; -import { Staking } from "./Staking.sol"; -import "solidity-bytes-utils/contracts/BytesLib.sol"; -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "@openzeppelin/contracts/access/AccessControl.sol"; - -import "hardhat/console.sol"; - -// TODO: make the tests send PKPNFT into the constructor -// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it -// TODO: setRoutingData() for a batch of keys - -contract PubkeyRouter is AccessControl { - using EnumerableSet for EnumerableSet.AddressSet; - using EnumerableSet for EnumerableSet.Bytes32Set; - using EnumerableSet for EnumerableSet.UintSet; - using BytesLib for bytes; - - /* ========== TYPE DEFINITIONS ========== */ - - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN"); - bytes32 public constant ROUTER_ROLE = keccak256("ROUTER"); - - /* ========== STATE VARIABLES ========== */ - - PKPNFT public pkpNFT; - - struct PubkeyRoutingData { - bytes pubkey; - address stakingContract; - uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. - } - - struct Signature { - bytes32 r; - bytes32 s; - uint8 v; - } - - // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData - mapping(uint256 => PubkeyRoutingData) public pubkeys; - - // map the eth address to a pkp id - mapping(address => uint256) public ethAddressToPkpId; - - /* ========== CONSTRUCTOR ========== */ - constructor(address _pkpNft) { - pkpNFT = PKPNFT(_pkpNft); - _grantRole(ADMIN_ROLE, msg.sender); - _grantRole(ROUTER_ROLE, msg.sender); - _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE); - _setRoleAdmin(ROUTER_ROLE, ADMIN_ROLE); - } - - /* ========== VIEWS ========== */ - - /// get the routing data for a given key hash - function getRoutingData( - uint256 tokenId - ) external view returns (PubkeyRoutingData memory) { - return pubkeys[tokenId]; - } - - /// get if a given pubkey has routing data associated with it or not - function isRouted(uint256 tokenId) public view returns (bool) { - PubkeyRoutingData memory prd = pubkeys[tokenId]; - return - prd.pubkey.length != 0 && - prd.keyType != 0 && - prd.stakingContract != address(0); - } - - /// get the eth address for the keypair, as long as it's an ecdsa keypair - function getEthAddress(uint256 tokenId) public view returns (address) { - // only return addresses for ECDSA keys so that people don't - // send funds to a BLS key that would be irretrieveably lost - if (pubkeys[tokenId].keyType != 2) { - return address(0); - } - return deriveEthAddressFromPubkey(pubkeys[tokenId].pubkey); - } - - /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress - function getPubkey(uint256 tokenId) public view returns (bytes memory) { - return pubkeys[tokenId].pubkey; - } - - function deriveEthAddressFromPubkey( - bytes memory pubkey - ) public pure returns (address) { - // remove 0x04 prefix - bytes32 hashed = keccak256(pubkey.slice(1, 64)); - return address(uint160(uint256(hashed))); - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - /// register a pubkey and routing data for a given key hash - // the person asking the nodes to generate the keys will collect signatures from them and then call this function to route the key - - // FIXME this is vulnerable to passing the same signature in 10 times. we don't check that the sigs are unique, or that they're from independent nodes. - // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually. - function setRoutingData( - uint256 tokenId, - bytes memory pubkey, - address stakingContractAddress, - uint256 keyType, - Signature[] memory signatures - ) public { - require( - hasRole(ROUTER_ROLE, msg.sender), - "PubkeyRouter: must have router role" - ); - Staking stakingContract = Staking(stakingContractAddress); - require( - signatures.length == - stakingContract.getValidatorsInCurrentEpochLength(), - "PubkeyRouter: incorrect number of signatures" - ); - require( - tokenId == uint256(keccak256(pubkey)), - "tokenId does not match hashed pubkey" - ); - require( - !isRouted(tokenId), - "PubkeyRouter: pubkey already has routing data" - ); - - // check the signatures - for (uint256 i = 0; i < signatures.length; i++) { - Signature memory sig = signatures[i]; - address signer = ECDSA.recover( - ECDSA.toEthSignedMessageHash(pubkey), - sig.v, - sig.r, - sig.s - ); - // console.log("signer: "); - // console.log(signer); - require( - stakingContract.isActiveValidatorByNodeAddress(signer), - "PubkeyRouter: signer is not active validator" - ); - } - - pubkeys[tokenId].pubkey = pubkey; - pubkeys[tokenId].stakingContract = stakingContractAddress; - pubkeys[tokenId].keyType = keyType; - - if (keyType == 2) { - address pkpAddress = deriveEthAddressFromPubkey(pubkey); - ethAddressToPkpId[pkpAddress] = tokenId; - } - - pkpNFT.pkpRouted(tokenId, keyType); - - emit PubkeyRoutingDataSet( - tokenId, - pubkey, - stakingContractAddress, - keyType - ); - } - - // a batch version of the above function - function setRoutingDataBatch( - uint256[] memory tokenIds, - bytes[] memory _pubkeys, - address stakingContract, - uint256 keyType, - Signature[][] memory signatures - ) public { - require( - tokenIds.length == _pubkeys.length && - tokenIds.length == signatures.length, - "PubkeyRouter: incorrect number of arguments" - ); - for (uint256 i = 0; i < tokenIds.length; i++) { - setRoutingData( - tokenIds[i], - _pubkeys[i], - stakingContract, - keyType, - signatures[i] - ); - } - } - - /// Set the pubkey and routing data for a given key hash - // this is only used by an admin in case of emergency. can prob be removed. - function setRoutingDataAsAdmin( - uint256 tokenId, - bytes memory pubkey, - address stakingContract, - uint256 keyType - ) public { - require( - hasRole(ADMIN_ROLE, msg.sender), - "PubkeyRouter: must have admin role" - ); - pubkeys[tokenId].pubkey = pubkey; - pubkeys[tokenId].stakingContract = stakingContract; - pubkeys[tokenId].keyType = keyType; - - if (keyType == 2) { - address pkpAddress = deriveEthAddressFromPubkey(pubkey); - ethAddressToPkpId[pkpAddress] = tokenId; - } - - pkpNFT.pkpRouted(tokenId, keyType); - - emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType); - } - - function setPkpNftAddress(address newPkpNftAddress) public { - require( - hasRole(ADMIN_ROLE, msg.sender), - "PubkeyRouter: must have admin role" - ); - pkpNFT = PKPNFT(newPkpNftAddress); - emit PkpNftAddressSet(newPkpNftAddress); - } - - /* ========== EVENTS ========== */ - - event PubkeyRoutingDataSet( - uint256 indexed tokenId, - bytes pubkey, - address stakingContract, - uint256 keyType - ); - - event PkpNftAddressSet(address newPkpNftAddress); -} diff --git a/contracts/RateLimitNFT.sol b/contracts/RateLimitNFT.sol deleted file mode 100644 index b22efdb..0000000 --- a/contracts/RateLimitNFT.sol +++ /dev/null @@ -1,305 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { ERC721Burnable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; -import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; -import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; -import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; - -import "hardhat/console.sol"; - -/// @title Rate Limit NFT -/// -/// @dev This is the contract for the Rate Limit NFTs -/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit -/// And how it works, is that you can buy X requestsPerKilosecond over a period of time -/// 1 requestsPerKilosecond = 0.001 requests per second and -/// 1000 requestsPerKilosecond = 1 request per second -contract RateLimitNFT is - ERC721("Rate Limit Increases on Lit Protocol", "RLI"), - Ownable, - ERC721Burnable, - ERC721Enumerable, - ReentrancyGuard -{ - using Strings for uint256; - /* ========== STATE VARIABLES ========== */ - - address public freeMintSigner; - uint256 public additionalRequestsPerKilosecondCost; - uint256 public tokenIdCounter; - uint256 public defaultRateLimitWindowSeconds = 60 * 60; // 60 mins - uint256 public RLIHolderRateLimitWindowSeconds = 5 * 60; // 5 mins - uint256 public freeRequestsPerRateLimitWindow = 10; - - mapping(uint256 => RateLimit) public capacity; - mapping(bytes32 => bool) public redeemedFreeMints; - - struct RateLimit { - uint256 requestsPerKilosecond; - uint256 expiresAt; - } - - /* ========== CONSTRUCTOR ========== */ - constructor() { - additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei - } - - /* ========== VIEWS ========== */ - - /// throws if the sig is bad or msg doesn't match - function freeMintSigTest( - uint256 expiresAt, - uint256 requestsPerKilosecond, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public view { - // make sure the msgHash matches the tokenId - // if these don't match, the user could use any old signature - // to mint any number of PKPs - // and this would be vulnerable to replay attacks - // FIXME this needs the whole "ethereum signed message: \27" thingy prepended to actually work - bytes32 expectedHash = prefixed( - keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond)) - ); - require( - expectedHash == msgHash, - "The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!" - ); - - // make sure it was actually signed by freeMintSigner - address recovered = ecrecover(msgHash, v, r, s); - require( - recovered == freeMintSigner, - "This freeMint was not signed by freeMintSigner. How embarassing." - ); - - // make sure it hasn't already been redeemed - require( - !redeemedFreeMints[msgHash], - "This freeMint has already been redeemed. How embarassing." - ); - } - - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) { - return - interfaceId == type(IERC721Enumerable).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - interfaceId == type(IERC721).interfaceId; - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override(ERC721, ERC721Enumerable) { - ERC721Enumerable._beforeTokenTransfer(from, to, tokenId); - } - - function calculateCost( - uint256 requestsPerKilosecond, - uint256 expiresAt - ) public view returns (uint256) { - require( - expiresAt > block.timestamp, - "The expiresAt must be in the future" - ); - require( - requestsPerKilosecond > 0, - "The requestsPerKilosecond must be greater than 0" - ); - - // calculate the duration - uint256 durationInSeconds = (expiresAt - block.timestamp); - - // calculate the cost - uint256 cost = (requestsPerKilosecond * - durationInSeconds * - additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000 - - return cost; - } - - function calculateRequestsPerKilosecond( - uint256 payingAmount, - uint256 expiresAt - ) public view returns (uint256) { - require( - expiresAt > block.timestamp, - "The expiresAt must be in the future" - ); - - // calculate the duration - uint256 durationInSeconds = (expiresAt - block.timestamp); - // console.log("durationInSeconds: "); - // console.log(durationInSeconds); - - // calculate the cost - uint256 requestsPerKilosecond = payingAmount / - ((durationInSeconds * additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000 - - return requestsPerKilosecond; - } - - function tokenURI( - uint256 tokenId - ) public view override returns (string memory) { - string - memory svgData = ""; - - string memory json = Base64.encode( - bytes( - string( - abi.encodePacked( - '{"name": "Lit Protocol Rate Limit Increase", "description": "This NFT entitles the holder to a rate limit increase on the Lit Protocol Network", "image_data": "', - bytes(svgData), - '","attributes": [{"display_type": "date", "trait_type": "Expiration Date", "value": ', - capacity[tokenId].expiresAt.toString(), - '}, {"display_type": "number", "trait_type": "Millirequests Per Second", "value": ', - capacity[tokenId].requestsPerKilosecond.toString(), - "}]}" - ) - ) - ) - ); - return string(abi.encodePacked("data:application/json;base64,", json)); - } - - function isExpired(uint256 tokenId) public view returns (bool) { - return capacity[tokenId].expiresAt <= block.timestamp; - } - - // Builds a prefixed hash to mimic the behavior of eth_sign. - function prefixed(bytes32 hash) public pure returns (bytes32) { - return - keccak256( - abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) - ); - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function. - function mint(uint256 expiresAt) public payable returns (uint256) { - tokenIdCounter++; - uint256 tokenId = tokenIdCounter; - - uint256 requestsPerKilosecond = calculateRequestsPerKilosecond( - msg.value, - expiresAt - ); - - // sanity check - uint256 cost = calculateCost(requestsPerKilosecond, expiresAt); - - require( - msg.value > 0 && msg.value >= cost, - "You must send the cost of this rate limit increase. To check the cost, use the calculateCost function." - ); - require(cost > 0, "The cost must be greater than 0"); - - _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt); - - return tokenId; - } - - function freeMint( - uint256 expiresAt, - uint256 requestsPerKilosecond, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public returns (uint256) { - tokenIdCounter++; - uint256 tokenId = tokenIdCounter; - - // this will panic if the sig is bad - freeMintSigTest(expiresAt, requestsPerKilosecond, msgHash, v, r, s); - redeemedFreeMints[msgHash] = true; - - _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt); - - return tokenId; - } - - function _mintWithoutValueCheck( - uint256 tokenId, - uint256 requestsPerKilosecond, - uint256 expiresAt - ) internal { - _safeMint(msg.sender, tokenId); - capacity[tokenId] = RateLimit(requestsPerKilosecond, expiresAt); - } - - function setAdditionalRequestsPerKilosecondCost( - uint256 newAdditionalRequestsPerKilosecondCost - ) public onlyOwner { - additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost; - emit AdditionalRequestsPerKilosecondCostSet( - newAdditionalRequestsPerKilosecondCost - ); - } - - function setFreeMintSigner(address newFreeMintSigner) public onlyOwner { - freeMintSigner = newFreeMintSigner; - emit FreeMintSignerSet(newFreeMintSigner); - } - - function withdraw() public onlyOwner nonReentrant { - uint256 withdrawAmount = address(this).balance; - (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); - require(sent); - emit Withdrew(withdrawAmount); - } - - function setRateLimitWindowSeconds( - uint256 newRateLimitWindowSeconds - ) public onlyOwner { - defaultRateLimitWindowSeconds = newRateLimitWindowSeconds; - emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds); - } - - function setRLIHolderRateLimitWindowSeconds( - uint256 newRLIHolderRateLimitWindowSeconds - ) public onlyOwner { - RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds; - emit RLIHolderRateLimitWindowSecondsSet( - newRLIHolderRateLimitWindowSeconds - ); - } - - function setFreeRequestsPerRateLimitWindow( - uint256 newFreeRequestsPerRateLimitWindow - ) public onlyOwner { - freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow; - emit FreeRequestsPerRateLimitWindowSet( - newFreeRequestsPerRateLimitWindow - ); - } - - /* ========== EVENTS ========== */ - - event AdditionalRequestsPerKilosecondCostSet( - uint256 newAdditionalRequestsPerKilosecondCost - ); - event FreeMintSignerSet(address indexed newFreeMintSigner); - event Withdrew(uint256 amount); - event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds); - event RLIHolderRateLimitWindowSecondsSet( - uint256 newRLIHolderRateLimitWindowSeconds - ); - event FreeRequestsPerRateLimitWindowSet( - uint256 newFreeRequestsPerRateLimitWindow - ); -} diff --git a/contracts/SoloNetPKP.sol b/contracts/SoloNetPKP.sol deleted file mode 100644 index 48990fe..0000000 --- a/contracts/SoloNetPKP.sol +++ /dev/null @@ -1,313 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { PubkeyRouter } from "./PubkeyRouter.sol"; -import { PKPPermissions } from "./PKPPermissions.sol"; -import { PKPNFTMetadata } from "./PKPNFTMetadata.sol"; -import { ERC721Burnable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; -import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; -import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; -import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import { Staking } from "./Staking.sol"; -import "solidity-bytes-utils/contracts/BytesLib.sol"; - -import "hardhat/console.sol"; - -// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn - -/// @title Programmable Keypair NFT -/// -/// @dev This is the contract for the PKP NFTs -/// -/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. -/// The owner can also grant signing permissions to other eth addresses -/// or lit actions -contract SoloNetPKP is - ERC721("Programmable Keypair", "PKP"), - Ownable, - ERC721Burnable, - ERC721Enumerable, - ReentrancyGuard -{ - using BytesLib for bytes; - using EnumerableSet for EnumerableSet.AddressSet; - - /* ========== STATE VARIABLES ========== */ - - PKPPermissions public pkpPermissions; - PKPNFTMetadata public pkpNftMetadata; - uint256 public mintCost; - address public freeMintSigner; - Staking public staking; - EnumerableSet.AddressSet permittedMinters; - - // map tokenId to the actual pubkey - mapping(uint256 => bytes) public pubkeys; - - // map the eth address to a pkp id - mapping(address => uint256) public ethAddressToPkpId; - - mapping(uint256 => bool) public redeemedFreeMintIds; - - /* ========== CONSTRUCTOR ========== */ - constructor() { - mintCost = 1; // 1 wei aka 0.000000000000000001 eth - freeMintSigner = msg.sender; - permittedMinters.add(msg.sender); - } - - /* ========== VIEWS ========== */ - - /// get the eth address for the keypair - function getEthAddress(uint256 tokenId) public view returns (address) { - // remove 0x04 prefix - bytes memory pubkey = pubkeys[tokenId].slice(1, 64); - bytes32 hashed = keccak256(pubkey); - return address(uint160(uint256(hashed))); - } - - /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress - function getPubkey(uint256 tokenId) public view returns (bytes memory) { - return pubkeys[tokenId]; - } - - /// throws if the sig is bad or msg doesn't match - function freeMintSigTest( - uint256 freeMintId, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public view { - bytes32 expectedHash = prefixed( - keccak256(abi.encodePacked(address(this), freeMintId)) - ); - require( - expectedHash == msgHash, - "The msgHash is not a hash of the tokenId. Explain yourself!" - ); - - // make sure it was actually signed by freeMintSigner - address recovered = ecrecover(msgHash, v, r, s); - require( - recovered == freeMintSigner, - "This freeMint was not signed by freeMintSigner. How embarassing." - ); - - // prevent reuse - require( - redeemedFreeMintIds[freeMintId] == false, - "This free mint ID has already been redeemed" - ); - } - - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) { - return - interfaceId == type(IERC721Enumerable).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - interfaceId == type(IERC721).interfaceId; - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override(ERC721, ERC721Enumerable) { - ERC721Enumerable._beforeTokenTransfer(from, to, tokenId); - } - - function tokenURI( - uint256 tokenId - ) public view override returns (string memory) { - console.log("getting token uri"); - bytes memory pubKey = getPubkey(tokenId); - console.log("got pubkey, getting eth address"); - address ethAddress = getEthAddress(tokenId); - console.log("calling tokenURI"); - - return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress); - } - - // Builds a prefixed hash to mimic the behavior of eth_sign. - function prefixed(bytes32 hash) public pure returns (bytes32) { - return - keccak256( - abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) - ); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function _getTokenIdToMint( - bytes memory pubkey - ) public view returns (uint256) { - uint256 tokenId = uint256(keccak256(pubkey)); - require(pubkeys[tokenId].length == 0, "This pubkey already exists"); - return tokenId; - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - function mint(bytes memory pubkey) public payable returns (uint256) { - require(msg.value == mintCost, "You must pay exactly mint cost"); - require( - permittedMinters.contains(tx.origin), - "You are not permitted to mint" - ); - - uint256 tokenId = _getTokenIdToMint(pubkey); - - _mintWithoutValueCheck(pubkey, msg.sender); - return tokenId; - } - - function mintGrantAndBurn( - bytes memory pubkey, - bytes memory ipfsCID - ) public payable returns (uint256) { - require(msg.value == mintCost, "You must pay exactly mint cost"); - require( - permittedMinters.contains(tx.origin), - "You are not permitted to mint" - ); - - uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this)); - - pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0)); - _burn(tokenId); - return tokenId; - } - - function freeMint( - bytes memory pubkey, - uint256 freeMintId, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public returns (uint256) { - require( - permittedMinters.contains(tx.origin), - "You are not permitted to mint" - ); - - // this will panic if the sig is bad - freeMintSigTest(freeMintId, msgHash, v, r, s); - uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender); - redeemedFreeMintIds[freeMintId] = true; - return tokenId; - } - - function freeMintGrantAndBurn( - bytes memory pubkey, - uint256 freeMintId, - bytes memory ipfsCID, - bytes32 msgHash, - uint8 v, - bytes32 r, - bytes32 s - ) public returns (uint256) { - require( - permittedMinters.contains(tx.origin), - "You are not permitted to mint" - ); - - // this will panic if the sig is bad - freeMintSigTest(freeMintId, msgHash, v, r, s); - uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this)); - redeemedFreeMintIds[freeMintId] = true; - pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0)); - _burn(tokenId); - return tokenId; - } - - function _mintWithoutValueCheck( - bytes memory pubkey, - address to - ) internal returns (uint256) { - uint256 tokenId = uint256(keccak256(pubkey)); - require(pubkeys[tokenId].length == 0, "This pubkey already exists"); - pubkeys[tokenId] = pubkey; - - address pkpAddress = getEthAddress(tokenId); - ethAddressToPkpId[pkpAddress] = tokenId; - - if (to == address(this)) { - // permit unsafe transfer only to this contract, because it's going to be burned - _mint(to, tokenId); - } else { - _safeMint(to, tokenId); - } - - return tokenId; - } - - function setStakingAddress(address stakingAddress) public onlyOwner { - staking = Staking(stakingAddress); - emit StakingAddressSet(stakingAddress); - } - - function addPermittedMinter(address newPermittedMinter) public onlyOwner { - permittedMinters.add(newPermittedMinter); - emit MinterPermitted(newPermittedMinter); - } - - function removePermittedMinter( - address newPermittedMinter - ) public onlyOwner { - permittedMinters.remove(newPermittedMinter); - emit MinterRevoked(newPermittedMinter); - } - - function setPkpNftMetadataAddress( - address pkpNftMetadataAddress - ) public onlyOwner { - pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress); - emit PkpNftMetadataAddressSet(pkpNftMetadataAddress); - } - - function setPkpPermissionsAddress( - address pkpPermissionsAddress - ) public onlyOwner { - pkpPermissions = PKPPermissions(pkpPermissionsAddress); - emit PkpPermissionsAddressSet(pkpPermissionsAddress); - } - - function setMintCost(uint256 newMintCost) public onlyOwner { - mintCost = newMintCost; - emit MintCostSet(newMintCost); - } - - function setFreeMintSigner(address newFreeMintSigner) public onlyOwner { - freeMintSigner = newFreeMintSigner; - emit FreeMintSignerSet(newFreeMintSigner); - } - - function withdraw() public onlyOwner nonReentrant { - uint256 withdrawAmount = address(this).balance; - (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); - require(sent); - emit Withdrew(withdrawAmount); - } - - /* ========== EVENTS ========== */ - - event StakingAddressSet(address indexed stakingAddress); - event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress); - event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress); - event MintCostSet(uint256 newMintCost); - event FreeMintSignerSet(address indexed newFreeMintSigner); - event Withdrew(uint256 amount); - event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType); - event MinterPermitted(address indexed minter); - event MinterRevoked(address indexed minter); -} diff --git a/contracts/SoloNetPKPHelper.sol b/contracts/SoloNetPKPHelper.sol deleted file mode 100644 index 5f67f4f..0000000 --- a/contracts/SoloNetPKPHelper.sol +++ /dev/null @@ -1,177 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { PKPPermissions } from "./PKPPermissions.sol"; -import { SoloNetPKP } from "./SoloNetPKP.sol"; -import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; -import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; - -/// @title PKP Helper Contract -/// -/// @dev This is the contract that helps minting PKPs -/// -/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. -/// The owner can also grant signing permissions to other eth addresses -/// or lit actions -contract SoloNetPKPHelper is Ownable, IERC721Receiver { - /* ========== STATE VARIABLES ========== */ - - SoloNetPKP public pkpNFT; - PKPPermissions public pkpPermissions; - - /* ========== CONSTRUCTOR ========== */ - constructor(address _pkpNft, address _pkpPermissions) { - pkpNFT = SoloNetPKP(_pkpNft); - pkpPermissions = PKPPermissions(_pkpPermissions); - } - - /* ========== VIEWS ========== */ - - /* ========== MUTATIVE FUNCTIONS ========== */ - - function mintAndAddAuthMethods( - bytes memory pubkey, - uint256[] memory permittedAuthMethodTypes, - bytes[] memory permittedAuthMethodIds, - bytes[] memory permittedAuthMethodPubkeys, - uint256[][] memory permittedAuthMethodScopes, - bool addPkpEthAddressAsPermittedAddress, - bool sendPkpToItself - ) public payable returns (uint256) { - return - mintAndAddAuthMethodsWithTypes( - pubkey, - new bytes[](0), // permitted ipfs CIDs - new uint256[][](0), // permitted ipfs CIDs scopes - new address[](0), // permitted addresses - new uint256[][](0), // permitted addresses scopes - permittedAuthMethodTypes, - permittedAuthMethodIds, - permittedAuthMethodPubkeys, - permittedAuthMethodScopes, - addPkpEthAddressAsPermittedAddress, - sendPkpToItself - ); - } - - function mintAndAddAuthMethodsWithTypes( - bytes memory pubkey, - bytes[] memory permittedIpfsCIDs, - uint256[][] memory permittedIpfsCIDScopes, - address[] memory permittedAddresses, - uint256[][] memory permittedAddressScopes, - uint256[] memory permittedAuthMethodTypes, - bytes[] memory permittedAuthMethodIds, - bytes[] memory permittedAuthMethodPubkeys, - uint256[][] memory permittedAuthMethodScopes, - bool addPkpEthAddressAsPermittedAddress, - bool sendPkpToItself - ) public payable returns (uint256) { - // mint the nft and forward the funds - uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey); - - // sanity checking array lengths - require( - permittedIpfsCIDs.length == permittedIpfsCIDScopes.length, - "PKPHelper: ipfs cid and scope array lengths must match" - ); - require( - permittedAddresses.length == permittedAddressScopes.length, - "PKPHelper: address and scope array lengths must match" - ); - require( - permittedAuthMethodTypes.length == permittedAuthMethodIds.length, - "PKPHelper: auth method type and id array lengths must match" - ); - require( - permittedAuthMethodTypes.length == - permittedAuthMethodPubkeys.length, - "PKPHelper: auth method type and pubkey array lengths must match" - ); - require( - permittedAuthMethodTypes.length == permittedAuthMethodScopes.length, - "PKPHelper: auth method type and scopes array lengths must match" - ); - - // permit the action - if (permittedIpfsCIDs.length != 0) { - for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) { - pkpPermissions.addPermittedAction( - tokenId, - permittedIpfsCIDs[i], - permittedIpfsCIDScopes[i] - ); - } - } - - // permit the address - if (permittedAddresses.length != 0) { - for (uint256 i = 0; i < permittedAddresses.length; i++) { - pkpPermissions.addPermittedAddress( - tokenId, - permittedAddresses[i], - permittedAddressScopes[i] - ); - } - } - - // permit the auth method - if (permittedAuthMethodTypes.length != 0) { - for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) { - pkpPermissions.addPermittedAuthMethod( - tokenId, - PKPPermissions.AuthMethod( - permittedAuthMethodTypes[i], - permittedAuthMethodIds[i], - permittedAuthMethodPubkeys[i] - ), - permittedAuthMethodScopes[i] - ); - } - } - - address pkpEthAddress = pkpNFT.getEthAddress(tokenId); - - // add the pkp eth address as a permitted address - if (addPkpEthAddressAsPermittedAddress) { - pkpPermissions.addPermittedAddress( - tokenId, - pkpEthAddress, - new uint256[](0) - ); - } - - if (sendPkpToItself) { - pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId); - } else { - pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId); - } - - return tokenId; - } - - function setPkpNftAddress(address newPkpNftAddress) public onlyOwner { - pkpNFT = SoloNetPKP(newPkpNftAddress); - } - - function setPkpPermissionsAddress( - address newPkpPermissionsAddress - ) public onlyOwner { - pkpPermissions = PKPPermissions(newPkpPermissionsAddress); - } - - function onERC721Received( - address /* operator */, - address /* from */, - uint256 /* tokenId */, - bytes calldata /* data */ - ) external view override returns (bytes4) { - // only accept transfers from the pkpNft contract - require( - msg.sender == address(pkpNFT), - "PKPHelper: only accepts transfers from the PKPNFT contract" - ); - return this.onERC721Received.selector; - } -} diff --git a/contracts/Staking.sol b/contracts/Staking.sol deleted file mode 100644 index 35d370c..0000000 --- a/contracts/Staking.sol +++ /dev/null @@ -1,661 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.17; - -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; -import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; - -import "hardhat/console.sol"; - -contract Staking is ReentrancyGuard, Pausable, Ownable { - using EnumerableSet for EnumerableSet.AddressSet; - - /* ========== STATE VARIABLES ========== */ - - enum States { - Active, - NextValidatorSetLocked, - ReadyForNextEpoch, - Unlocked, - Paused - } - - // this enum is not used, and instead we use an integer so that - // we can add more reasons after the contract is deployed. - // This enum is kept in the comments here for reference. - // enum KickReason { - // NULLREASON, // 0 - // UNRESPONSIVE, // 1 - // BAD_ATTESTATION // 2 - // } - - States public state = States.Active; - - ERC20Burnable public stakingToken; - - struct Epoch { - uint256 epochLength; - uint256 number; - uint256 endBlock; // - uint256 retries; // incremented upon failure to advance and subsequent unlock - uint256 timeout; // timeout in blocks, where the nodes can be unlocked. - } - - Epoch public epoch; - - uint256 public tokenRewardPerTokenPerEpoch; - - uint256 public minimumStake; - uint256 public totalStaked; - - // tokens slashed when kicked - uint256 public kickPenaltyPercent; - - EnumerableSet.AddressSet validatorsInCurrentEpoch; - EnumerableSet.AddressSet validatorsInNextEpoch; - EnumerableSet.AddressSet validatorsKickedFromNextEpoch; - - struct Validator { - uint32 ip; - uint128 ipv6; - uint32 port; - address nodeAddress; - uint256 balance; - uint256 reward; - uint256 senderPubKey; - uint256 receiverPubKey; - } - - struct VoteToKickValidatorInNextEpoch { - uint256 votes; - mapping(address => bool) voted; - } - - // list of all validators, even ones that are not in the current or next epoch - // maps STAKER address to Validator struct - mapping(address => Validator) public validators; - - // stakers join by staking, but nodes need to be able to vote to kick. - // to avoid node operators having to run a hotwallet with their staking private key, - // the node gets it's own private key that it can use to vote to kick, - // or signal that the next epoch is ready. - // this mapping lets you go from the nodeAddressto the stakingAddress. - mapping(address => address) public nodeAddressToStakerAddress; - - // after the validator set is locked, nodes vote that they have successfully completed the PSS - // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance - mapping(address => bool) public readyForNextEpoch; - - // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they - // are removed from the next validator set - mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch)) - public votesToKickValidatorsInNextEpoch; - - // resolver contract address. the resolver contract is used to lookup other contract addresses. - address public resolverContractAddress; - - /* ========== CONSTRUCTOR ========== */ - constructor(address _stakingToken) { - stakingToken = ERC20Burnable(_stakingToken); - epoch = Epoch({ - epochLength: 80, - number: 1, - endBlock: block.number + 1, - retries: 0, - timeout: 80 - }); - // 0.05 tokens per token staked meaning a 5% per epoch inflation rate - tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20; - // 1 token minimum stake - minimumStake = 1 * (10 ** stakingToken.decimals()); - kickPenaltyPercent = 0; - } - - /* ========== VIEWS ========== */ - function isActiveValidator(address account) external view returns (bool) { - return validatorsInCurrentEpoch.contains(account); - } - - function isActiveValidatorByNodeAddress( - address account - ) external view returns (bool) { - return - validatorsInCurrentEpoch.contains( - nodeAddressToStakerAddress[account] - ); - } - - function rewardOf(address account) external view returns (uint256) { - return validators[account].reward; - } - - function balanceOf(address account) external view returns (uint256) { - return validators[account].balance; - } - - function getVotingStatusToKickValidator( - uint256 epochNumber, - address validatorStakerAddress, - address voterStakerAddress - ) external view returns (uint256, bool) { - VoteToKickValidatorInNextEpoch - storage votingStatus = votesToKickValidatorsInNextEpoch[ - epochNumber - ][validatorStakerAddress]; - return (votingStatus.votes, votingStatus.voted[voterStakerAddress]); - } - - function getValidatorsInCurrentEpoch() - external - view - returns (address[] memory) - { - address[] memory values = new address[]( - validatorsInCurrentEpoch.length() - ); - uint256 validatorLength = validatorsInCurrentEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - values[i] = validatorsInCurrentEpoch.at(i); - } - return values; - } - - function getValidatorsInCurrentEpochLength() - external - view - returns (uint256) - { - return validatorsInCurrentEpoch.length(); - } - - function getValidatorsInNextEpoch() - external - view - returns (address[] memory) - { - address[] memory values = new address[](validatorsInNextEpoch.length()); - uint256 validatorLength = validatorsInNextEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - values[i] = validatorsInNextEpoch.at(i); - } - return values; - } - - function isReadyForNextEpoch() public view returns (bool) { - uint256 total = 0; - uint256 validatorLength = validatorsInNextEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) { - total++; - } - } - if ((total >= validatorCountForConsensus())) { - // 2/3 of validators must be ready - return true; - } - return false; - } - - function shouldKickValidator( - address stakerAddress - ) public view returns (bool) { - VoteToKickValidatorInNextEpoch - storage vk = votesToKickValidatorsInNextEpoch[epoch.number][ - stakerAddress - ]; - if (vk.votes >= validatorCountForConsensus()) { - // 2/3 of validators must vote - return true; - } - return false; - } - - // these could be checked with uint return value with the state getter, but included defensively in case more states are added. - function validatorsInNextEpochAreLocked() public view returns (bool) { - return state == States.NextValidatorSetLocked; - } - - function validatorStateIsActive() public view returns (bool) { - return state == States.Active; - } - - function validatorStateIsUnlocked() public view returns (bool) { - return state == States.Unlocked; - } - - // currently set to 2/3. this could be changed to be configurable. - function validatorCountForConsensus() public view returns (uint256) { - if (validatorsInCurrentEpoch.length() <= 2) { - return 1; - } - return (validatorsInCurrentEpoch.length() * 2) / 3; - } - - /* ========== MUTATIVE FUNCTIONS ========== */ - - /// Lock in the validators for the next epoch - function lockValidatorsForNextEpoch() public { - require( - block.number >= epoch.endBlock, - "Enough blocks have not elapsed since the last epoch" - ); - require( - state == States.Active || state == States.Unlocked, - "Must be in active or unlocked state" - ); - - state = States.NextValidatorSetLocked; - emit StateChanged(state); - } - - /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress. - function signalReadyForNextEpoch() public { - address stakerAddress = nodeAddressToStakerAddress[msg.sender]; - require( - state == States.NextValidatorSetLocked || - state == States.ReadyForNextEpoch, - "Must be in state NextValidatorSetLocked or ReadyForNextEpoch" - ); - // at the first epoch, validatorsInCurrentEpoch is empty - if (epoch.number != 1) { - require( - validatorsInNextEpoch.contains(stakerAddress), - "Validator is not in the next epoch" - ); - } - readyForNextEpoch[stakerAddress] = true; - emit ReadyForNextEpoch(stakerAddress); - - if (isReadyForNextEpoch()) { - state = States.ReadyForNextEpoch; - emit StateChanged(state); - } - } - - /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry - function unlockValidatorsForNextEpoch() public { - // the deadline to advance is thus epoch.endBlock + epoch.timeout - require( - block.number >= epoch.endBlock + epoch.timeout, - "Enough blocks have not elapsed since the last epoch" - ); - require( - state == States.NextValidatorSetLocked, - "Must be in NextValidatorSetLocked" - ); - - uint256 validatorLength = validatorsInNextEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - readyForNextEpoch[validatorsInNextEpoch.at(i)] = false; - } - - epoch.retries++; - - state = States.Unlocked; - emit StateChanged(state); - } - - /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers - function advanceEpoch() public { - require( - block.number >= epoch.endBlock, - "Enough blocks have not elapsed since the last epoch" - ); - require( - state == States.ReadyForNextEpoch, - "Must be in ready for next epoch state" - ); - require( - isReadyForNextEpoch() == true, - "Not enough validators are ready for the next epoch" - ); - - // reward the validators - uint256 validatorLength = validatorsInCurrentEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - address validatorAddress = validatorsInCurrentEpoch.at(i); - validators[validatorAddress].reward += - (tokenRewardPerTokenPerEpoch * - validators[validatorAddress].balance) / - 10 ** stakingToken.decimals(); - } - - // set the validators to the new validator set - // ideally we could just do this: - // validatorsInCurrentEpoch = validatorsInNextEpoch; - // but solidity doesn't allow that, so we have to do it manually - - // clear out validators in current epoch - while (validatorsInCurrentEpoch.length() > 0) { - validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0)); - } - - // copy validators from next epoch to current epoch - validatorLength = validatorsInNextEpoch.length(); - for (uint256 i = 0; i < validatorLength; i++) { - validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i)); - - // clear out readyForNextEpoch - readyForNextEpoch[validatorsInNextEpoch.at(i)] = false; - } - - epoch.number++; - epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock + - - state = States.Active; - emit StateChanged(state); - } - - /// Stake and request to join the validator set - /// @param amount The amount of tokens to stake - /// @param ip The IP address of the node - /// @param port The port of the node - function stakeAndJoin( - uint256 amount, - uint32 ip, - uint128 ipv6, - uint32 port, - address nodeAddress, - uint256 senderPubKey, - uint256 receiverPubKey - ) public whenNotPaused { - stake(amount); - requestToJoin( - ip, - ipv6, - port, - nodeAddress, - senderPubKey, - receiverPubKey - ); - } - - /// Stake tokens for a validator - function stake(uint256 amount) public nonReentrant { - require(amount > 0, "Cannot stake 0"); - - stakingToken.transferFrom(msg.sender, address(this), amount); - validators[msg.sender].balance += amount; - - totalStaked += amount; - - emit Staked(msg.sender, amount); - } - - function requestToJoin( - uint32 ip, - uint128 ipv6, - uint32 port, - address nodeAddress, - uint256 senderPubKey, - uint256 receiverPubKey - ) public nonReentrant { - uint256 amountStaked = validators[msg.sender].balance; - require( - amountStaked >= minimumStake, - "Stake must be greater than or equal to minimumStake" - ); - require( - state == States.Active || - state == States.Unlocked || - state == States.Paused, - "Must be in Active or Unlocked state to request to join" - ); - - // make sure they haven't been kicked - require( - validatorsKickedFromNextEpoch.contains(msg.sender) == false, - "You cannot rejoin if you have been kicked until the next epoch" - ); - - validators[msg.sender].ip = ip; - validators[msg.sender].ipv6 = ipv6; - validators[msg.sender].port = port; - validators[msg.sender].nodeAddress = nodeAddress; - validators[msg.sender].senderPubKey = senderPubKey; - validators[msg.sender].receiverPubKey = receiverPubKey; - nodeAddressToStakerAddress[nodeAddress] = msg.sender; - - validatorsInNextEpoch.add(msg.sender); - - emit RequestToJoin(msg.sender); - } - - /// Withdraw staked tokens. This can only be done by users who are not active in the validator set. - /// @param amount The amount of tokens to withdraw - function withdraw(uint256 amount) public nonReentrant { - require(amount > 0, "Cannot withdraw 0"); - - require( - validatorsInCurrentEpoch.contains(msg.sender) == false, - "Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave" - ); - - require( - validators[msg.sender].balance >= amount, - "Not enough tokens to withdraw" - ); - - totalStaked = totalStaked - amount; - validators[msg.sender].balance = - validators[msg.sender].balance - - amount; - stakingToken.transfer(msg.sender, amount); - emit Withdrawn(msg.sender, amount); - } - - /// Request to leave in the next Epoch - function requestToLeave() public nonReentrant { - require( - state == States.Active || - state == States.Unlocked || - state == States.Paused, - "Must be in Active or Unlocked state to request to leave" - ); - if (validatorsInNextEpoch.contains(msg.sender)) { - // remove them - validatorsInNextEpoch.remove(msg.sender); - } - emit RequestToLeave(msg.sender); - } - - /// Transfer any outstanding reward tokens - function getReward() public nonReentrant { - uint256 reward = validators[msg.sender].reward; - if (reward > 0) { - validators[msg.sender].reward = 0; - stakingToken.transfer(msg.sender, reward); - emit RewardPaid(msg.sender, reward); - } - } - - /// Exit staking and get any outstanding rewards - function exit() public { - withdraw(validators[msg.sender].balance); - getReward(); - } - - /// If more than the threshold of validators vote to kick someone, kick them. - /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress - function kickValidatorInNextEpoch( - address validatorStakerAddress, - uint256 reason, - bytes calldata data - ) public nonReentrant { - address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender]; - require( - stakerAddressOfSender != address(0), - "Could not map your nodeAddress to your stakerAddress" - ); - require( - validatorsInNextEpoch.contains(stakerAddressOfSender), - "You must be a validator in the next epoch to kick someone from the next epoch" - ); - require( - votesToKickValidatorsInNextEpoch[epoch.number][ - validatorStakerAddress - ].voted[stakerAddressOfSender] == false, - "You can only vote to kick someone once per epoch" - ); - - // Vote to kick - votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress] - .votes++; - votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress] - .voted[stakerAddressOfSender] = true; - - if ( - validatorsInNextEpoch.contains(validatorStakerAddress) && - shouldKickValidator(validatorStakerAddress) - ) { - // remove from next validator set - validatorsInNextEpoch.remove(validatorStakerAddress); - // block them from rejoining the next epoch - validatorsKickedFromNextEpoch.add(validatorStakerAddress); - // slash the stake - uint256 amountToBurn = (validators[validatorStakerAddress].balance * - kickPenaltyPercent) / 100; - validators[validatorStakerAddress].balance -= amountToBurn; - totalStaked -= amountToBurn; - stakingToken.burn(amountToBurn); - // shame them with an event - emit ValidatorKickedFromNextEpoch( - validatorStakerAddress, - amountToBurn - ); - } - - emit VotedToKickValidatorInNextEpoch( - stakerAddressOfSender, - validatorStakerAddress, - reason, - data - ); - } - - /// Set the IP and port of your node - /// @param ip The ip address of your node - /// @param port The port of your node - function setIpPortNodeAddressAndCommunicationPubKeys( - uint32 ip, - uint128 ipv6, - uint32 port, - address nodeAddress, - uint256 senderPubKey, - uint256 receiverPubKey - ) public { - validators[msg.sender].ip = ip; - validators[msg.sender].ipv6 = ipv6; - validators[msg.sender].port = port; - validators[msg.sender].nodeAddress = nodeAddress; - validators[msg.sender].senderPubKey = senderPubKey; - validators[msg.sender].receiverPubKey = receiverPubKey; - } - - function setEpochLength(uint256 newEpochLength) public onlyOwner { - epoch.epochLength = newEpochLength; - emit EpochLengthSet(newEpochLength); - } - - function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner { - epoch.timeout = newEpochTimeout; - emit EpochTimeoutSet(newEpochTimeout); - } - - function setStakingToken(address newStakingTokenAddress) public onlyOwner { - stakingToken = ERC20Burnable(newStakingTokenAddress); - emit StakingTokenSet(newStakingTokenAddress); - } - - function setTokenRewardPerTokenPerEpoch( - uint256 newTokenRewardPerTokenPerEpoch - ) public onlyOwner { - tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch; - emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch); - } - - function setMinimumStake(uint256 newMinimumStake) public onlyOwner { - minimumStake = newMinimumStake; - emit MinimumStakeSet(newMinimumStake); - } - - function setKickPenaltyPercent( - uint256 newKickPenaltyPercent - ) public onlyOwner { - kickPenaltyPercent = newKickPenaltyPercent; - emit KickPenaltyPercentSet(newKickPenaltyPercent); - } - - function setResolverContractAddress( - address newResolverContractAddress - ) public onlyOwner { - resolverContractAddress = newResolverContractAddress; - - emit ResolverContractAddressSet(newResolverContractAddress); - } - - function setEpochState(States newState) public onlyOwner { - state = newState; - emit StateChanged(newState); - } - - function pauseEpoch() public onlyOwner { - state = States.Paused; - emit StateChanged(States.Paused); - } - - function adminKickValidatorInNextEpoch( - address validatorStakerAddress - ) public nonReentrant onlyOwner { - // remove from next validator set - validatorsInNextEpoch.remove(validatorStakerAddress); - // block them from rejoining the next epoch - validatorsKickedFromNextEpoch.add(validatorStakerAddress); - emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0); - } - - function adminSlashValidator( - address validatorStakerAddress, - uint256 amountToBurn - ) public nonReentrant onlyOwner { - validators[validatorStakerAddress].balance -= amountToBurn; - totalStaked -= amountToBurn; - stakingToken.burn(amountToBurn); - emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn); - } - - /* ========== EVENTS ========== */ - - event Staked(address indexed staker, uint256 amount); - event Withdrawn(address indexed staker, uint256 amount); - event RewardPaid(address indexed staker, uint256 reward); - event RewardsDurationUpdated(uint256 newDuration); - event RequestToJoin(address indexed staker); - event RequestToLeave(address indexed staker); - event Recovered(address token, uint256 amount); - event ReadyForNextEpoch(address indexed staker); - event StateChanged(States newState); - event VotedToKickValidatorInNextEpoch( - address indexed reporter, - address indexed validatorStakerAddress, - uint256 indexed reason, - bytes data - ); - event ValidatorKickedFromNextEpoch( - address indexed staker, - uint256 amountBurned - ); - - // onlyOwner events - event EpochLengthSet(uint256 newEpochLength); - event EpochTimeoutSet(uint256 newEpochTimeout); - event StakingTokenSet(address newStakingTokenAddress); - event TokenRewardPerTokenPerEpochSet( - uint256 newTokenRewardPerTokenPerEpoch - ); - event MinimumStakeSet(uint256 newMinimumStake); - event KickPenaltyPercentSet(uint256 newKickPenaltyPercent); - event ResolverContractAddressSet(address newResolverContractAddress); -} diff --git a/contracts/domain-wallets/DomainWalletRegistry.sol b/contracts/domain-wallets/DomainWalletRegistry.sol new file mode 100644 index 0000000..e416e26 --- /dev/null +++ b/contracts/domain-wallets/DomainWalletRegistry.sol @@ -0,0 +1,72 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; + +import { LibDomainWalletRegistryStorage } from "./DomainWalletRegistry/LibDomainWalletRegistryStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +struct ConstructorArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract DomainWalletRegistry { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + ConstructorArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + LibDomainWalletRegistryStorage.getStorage().domainCharLimit = 32; + // Code can be added here to perform actions and set state variables. + LibDomainWalletRegistryStorage + .getStorage() + .contractResolver = ContractResolver(_args.contractResolver); + LibDomainWalletRegistryStorage.getStorage().env = _args.env; + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryFacet.sol b/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryFacet.sol new file mode 100644 index 0000000..485c207 --- /dev/null +++ b/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryFacet.sol @@ -0,0 +1,231 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { LibDomainWalletRegistryStorage } from "./LibDomainWalletRegistryStorage.sol"; +import { PKPHelper } from "../../lit-node/PKPHelper.sol"; +import { DomainWalletRegistryViewsFacet } from "./DomainWalletRegistryViewsFacet.sol"; + +contract DomainWalletRegistryFacet { + /* ========== ERRORS ========== */ + error InvalidNftMetadataCollectionLength( + uint256 metadataCount, + uint256 validMetadataCount + ); + error MaximumCharacterLimitExceeded(uint length, bytes uri); + error CallerNotOwner(); + + /* ========== EVENTS ========== */ + event Registered(uint64 id, bytes subDomain, uint ttl, uint256 tokenId); + event Removed(uint256 tokenId, bytes subDomain); + event Revoked(uint256 tokenId, bytes subDomain); + event Expired(bytes subDomain, uint256 tokenId, uint ttl); + + /* ========== Modifiers ========== */ + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== Views ========== */ + + function s() + internal + pure + returns ( + LibDomainWalletRegistryStorage.DomainWalletRegistryStorage storage + ) + { + return LibDomainWalletRegistryStorage.getStorage(); + } + + function views() internal view returns (DomainWalletRegistryViewsFacet) { + return DomainWalletRegistryViewsFacet(address(this)); + } + + /* ========== Mutative Functions ========== */ + + function hasExpired(uint256 pkpTokenId) public onlyOwner returns (bool) { + uint ttl = s().pkpOwners[pkpTokenId].ttl; + bytes memory uri = s().pkpOwners[pkpTokenId].uri; + bool isExpired = ttl < block.timestamp; + + if (isExpired) { + emit Expired(uri, pkpTokenId, ttl); + return true; + } + } + + function setPKPMetadata( + uint256 pkpTokenId, + string[] memory nftMetadata + ) public onlyOwner { + PKPHelper pkpHelper = PKPHelper(views().getPkpHelperAddress()); + pkpHelper.setPkpMetadata(pkpTokenId, nftMetadata); + } + + function registerDomain( + bytes memory userId, + bytes memory uri, + uint ttl, + uint256 pkpTokenId, + string[] memory nftMetadata + ) public onlyOwner returns (uint256) { + require( + nftMetadata.length == 2, + "DomainWalletRegistry: metadata name and url must be set in metadata" + ); + if (nftMetadata.length != 2) { + revert InvalidNftMetadataCollectionLength(nftMetadata.length, 2); + } + if (uri.length > s().domainCharLimit) { + revert MaximumCharacterLimitExceeded(uri.length, uri); + } + + PKPHelper pkpHelper = PKPHelper(views().getPkpHelperAddress()); + _registerDomain(userId, uri, pkpTokenId, ttl); + pkpHelper.setPkpMetadata(pkpTokenId, nftMetadata); + return pkpTokenId; + } + + function _registerDomain( + bytes memory userId, + bytes memory uri, + uint256 pkpTokenId, + uint ttl + ) internal { + views().checkRegistration(uri); + + s().idCounter = s().idCounter + 1; + uint64 id = s().idCounter; + s().domainWallets[id].user_id = userId; + s().domainWallets[id].pkpTokenId = pkpTokenId; + s().domainWallets[id].uri = uri; + s().domainWallets[id].ttl = ttl; + s().domainWallets[id].isRegistered = true; + s().domainWallets[id].isWallet = true; + s().domainWallets[id].id = id; + // Set the value in the pkpOwners map from the domainWallets map to avoid memory storage. + s().pkpOwners[pkpTokenId] = s().domainWallets[id]; + // Set the domain as a lookup to the pkp + s().ownerLookup[uri] = pkpTokenId; + + emit Registered(id, userId, ttl, pkpTokenId); + } + + function registerPKP( + uint64 id, + uint256 pkpTokenId + ) public onlyOwner returns (bool) { + if (s().domainWallets[id].isWallet == false) { + return false; + } + + s().domainWallets[id].pkpTokenId = pkpTokenId; + + return true; + } + + function removeDomain(uint256 pkpTokenId) public onlyOwner returns (bool) { + PKPHelper pkpHelper = PKPHelper(views().getPkpHelperAddress()); + pkpHelper.removePkpMetadata(pkpTokenId); + + return _removeDomain(pkpTokenId); + } + + function _removeDomain(uint256 pkpTokenId) internal returns (bool) { + if (s().pkpOwners[pkpTokenId].isWallet == false) { + return false; + } + + uint64 id = s().pkpOwners[pkpTokenId].id; + + delete s().pkpOwners[pkpTokenId]; // delete the pkp ownership relationship + delete s().ownerLookup[s().domainWallets[id].uri]; + + s().domainWallets[id].isRegistered = false; + s().domainWallets[id].isWallet = false; + s().domainWallets[id].pkpTokenId = 0; // null the tokenId since the owner is no longer this pkp + s().domainWallets[id].user_id = hex"00"; // 0 out the bytes for the user id + s().domainWallets[id].cname = hex"00"; + emit Removed(id, s().domainWallets[id].user_id); + + return true; + } + + function updateDomainRecord( + uint256 pkpTokenId, + bytes memory record + ) public onlyOwner returns (bool) { + if (s().pkpOwners[pkpTokenId].isWallet == false) { + return false; + } + s().pkpOwners[pkpTokenId].cname = record; + s().domainWallets[s().pkpOwners[pkpTokenId].id].cname = s() + .pkpOwners[pkpTokenId] + .cname; + return true; + } + + function revokeDomain(uint256 pkpTokenId) public onlyOwner returns (bool) { + PKPHelper pkpHelper = PKPHelper(views().getPkpHelperAddress()); + pkpHelper.removePkpMetadata(pkpTokenId); + return _revokeDomain(pkpTokenId); + } + + function _revokeDomain(uint256 pkpTokenId) internal returns (bool) { + if (s().pkpOwners[pkpTokenId].isRegistered == false) { + return false; + } + + s().pkpOwners[pkpTokenId].isRegistered = false; + s().pkpOwners[pkpTokenId].pkpTokenId = 0; // null the tokenId since the owner is no longer this pkp; + s().pkpOwners[pkpTokenId].user_id = hex"00"; // 0 out the bytes for the user id + s().pkpOwners[pkpTokenId].cname = hex"00"; // 0 out the bytes for the record + + s().domainWallets[s().pkpOwners[pkpTokenId].id] = s().pkpOwners[ + pkpTokenId + ]; + + emit Revoked(pkpTokenId, s().pkpOwners[pkpTokenId].uri); + + return true; + } + + function registerDomainAndMintNext( + bytes memory userId, + bytes memory uri, + uint ttl, + uint256[] memory permittedAuthMethodTypes, + bytes[] memory permittedAuthMethodIds, + bytes[] memory permittedAuthMethodPubkeys, + uint256[][] memory permittedAuthMethodScopes, + string[] memory nftMetadata + ) public payable onlyOwner returns (uint256) { + PKPHelper pkpHelper = PKPHelper(views().getPkpHelperAddress()); + + views().checkRegistration(uri); + + if (nftMetadata.length != 2) { + revert InvalidNftMetadataCollectionLength(nftMetadata.length, 2); + } + // pass the message value down to the minting so the pkp mint has the correct mint cost. + uint256 tokenId = pkpHelper.mintNextAndAddDomainWalletMetadata{ + value: msg.value + }( + 2, + permittedAuthMethodTypes, + permittedAuthMethodIds, + permittedAuthMethodPubkeys, + permittedAuthMethodScopes, + nftMetadata, + true, + true + ); + + _registerDomain(userId, uri, tokenId, ttl); + + return tokenId; + } +} diff --git a/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryViewsFacet.sol b/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryViewsFacet.sol new file mode 100644 index 0000000..9c224fd --- /dev/null +++ b/contracts/domain-wallets/DomainWalletRegistry/DomainWalletRegistryViewsFacet.sol @@ -0,0 +1,93 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { LibDomainWalletRegistryStorage } from "./LibDomainWalletRegistryStorage.sol"; + +contract DomainWalletRegistryViewsFacet { + /* ========== ERRORS ========== */ + error DomainAlreadyRegistered(bytes uri, uint256 pkpTokenId); + + /* ========== VIEWS ========== */ + + function getStorage() + internal + pure + returns ( + LibDomainWalletRegistryStorage.DomainWalletRegistryStorage storage + ) + { + return LibDomainWalletRegistryStorage.getStorage(); + } + + function getDomainCharacterLimit() public view returns (uint) { + return getStorage().domainCharLimit; + } + + function getDomainWalletRegistryAddress() public view returns (address) { + return + getStorage().contractResolver.getContract( + getStorage().contractResolver.DOMAIN_WALLET_REGISTRY(), + getStorage().env + ); + } + + function getPkpHelperAddress() public view returns (address) { + return + getStorage().contractResolver.getContract( + getStorage().contractResolver.PKP_HELPER_CONTRACT(), + getStorage().env + ); + } + + function getPkpTokenId(uint64 id) public view returns (uint256) { + return + getStorage() + .pkpOwners[getStorage().domainWallets[id].pkpTokenId] + .pkpTokenId; + } + + function getDomainIdByTokenId( + uint256 pkpTokenId + ) public view returns (uint64) { + return getStorage().pkpOwners[pkpTokenId].id; + } + + function isOwner(uint256 pkpTokenId) public view returns (bool) { + return getStorage().pkpOwners[pkpTokenId].isRegistered; + } + + function isRouted(uint256 pkpTokenId) public view returns (bool) { + return getStorage().pkpOwners[pkpTokenId].isRegistered; + } + + function hasOwner(uint256 pkpTokenId) public view returns (bool) { + return getStorage().pkpOwners[pkpTokenId].isRegistered; + } + + function getDomainTokenIdByUri( + bytes memory uri + ) public view returns (uint256) { + return getStorage().ownerLookup[uri]; + } + + function getDomainUri( + uint256 pkpTokenId + ) public view returns (bytes memory) { + return getStorage().pkpOwners[pkpTokenId].uri; + } + + function getExpiration(uint256 pkpTokenId) public view returns (uint) { + return getStorage().pkpOwners[pkpTokenId].ttl; + } + + function getRecord(uint256 pkpTokenId) public view returns (bytes memory) { + return getStorage().pkpOwners[pkpTokenId].cname; + } + + function checkRegistration(bytes memory uri) public view { + if (getStorage().ownerLookup[uri] != 0) { + revert DomainAlreadyRegistered(uri, getStorage().ownerLookup[uri]); + } + } +} diff --git a/contracts/domain-wallets/DomainWalletRegistry/LibDomainWalletRegistryStorage.sol b/contracts/domain-wallets/DomainWalletRegistry/LibDomainWalletRegistryStorage.sol new file mode 100644 index 0000000..a14f7a6 --- /dev/null +++ b/contracts/domain-wallets/DomainWalletRegistry/LibDomainWalletRegistryStorage.sol @@ -0,0 +1,47 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +struct DomainWallet { + bytes user_id; + uint64 id; + uint256 pkpTokenId; + bytes uri; + uint ttl; + bool isWallet; + bool isRegistered; + bytes cname; +} + +library LibDomainWalletRegistryStorage { + bytes32 constant DOMAIN_WALLET_REGISTRY_POSITION = + keccak256("domainwalletregistry.storage"); + + struct DomainWalletRegistryStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + // id to domain wallet instance + mapping(uint64 => DomainWallet) domainWallets; + // pkpTokenId to DomainWallet + mapping(uint256 => DomainWallet) pkpOwners; + // mapping of domain to tokenId for look ups + mapping(bytes => uint256) ownerLookup; + // counter for tracking registrations + uint64 idCounter; + //tracks max characters allowed in a domain name, set in the constructor + uint domainCharLimit; + } + + // Return storage struct for reading and writing + function getStorage() + internal + pure + returns (DomainWalletRegistryStorage storage storageStruct) + { + bytes32 position = DOMAIN_WALLET_REGISTRY_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/facets/DiamondCutFacet.sol b/contracts/facets/DiamondCutFacet.sol new file mode 100644 index 0000000..89c3600 --- /dev/null +++ b/contracts/facets/DiamondCutFacet.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { LibDiamond } from "../libraries/LibDiamond.sol"; + +// Remember to add the loupe functions from DiamondLoupeFacet to the diamond. +// The loupe functions are required by the EIP2535 Diamonds standard + +contract DiamondCutFacet is IDiamondCut { + /// @notice Add/replace/remove any number of functions and optionally execute + /// a function with delegatecall + /// @param _diamondCut Contains the facet addresses and function selectors + /// @param _init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments + /// _calldata is executed with delegatecall on _init + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata _calldata + ) external override { + LibDiamond.enforceIsContractOwner(); + LibDiamond.diamondCut(_diamondCut, _init, _calldata); + } +} diff --git a/contracts/facets/DiamondLoupeFacet.sol b/contracts/facets/DiamondLoupeFacet.sol new file mode 100644 index 0000000..6396cbe --- /dev/null +++ b/contracts/facets/DiamondLoupeFacet.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +// The functions in DiamondLoupeFacet MUST be added to a diamond. +// The EIP-2535 Diamond standard requires these functions. + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; + +contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { + // Diamond Loupe Functions + //////////////////////////////////////////////////////////////////// + /// These functions are expected to be called frequently by tools. + // + // struct Facet { + // address facetAddress; + // bytes4[] functionSelectors; + // } + /// @notice Gets all facets and their selectors. + /// @return facets_ Facet + function facets() external view override returns (Facet[] memory facets_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facets_ = new Facet[](selectorCount); + // create an array for counting the number of selectors for each facet + uint16[] memory numFacetSelectors = new uint16[](selectorCount); + // total number of facets + uint256 numFacets; + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + bool continueLoop = false; + // find the functionSelectors array for selector and add selector to it + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facets_[facetIndex].facetAddress == facetAddress_) { + facets_[facetIndex].functionSelectors[ + numFacetSelectors[facetIndex] + ] = selector; + numFacetSelectors[facetIndex]++; + continueLoop = true; + break; + } + } + // if functionSelectors array exists for selector then continue loop + if (continueLoop) { + continueLoop = false; + continue; + } + // create a new functionSelectors array for selector + facets_[numFacets].facetAddress = facetAddress_; + facets_[numFacets].functionSelectors = new bytes4[](selectorCount); + facets_[numFacets].functionSelectors[0] = selector; + numFacetSelectors[numFacets] = 1; + numFacets++; + } + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + uint256 numSelectors = numFacetSelectors[facetIndex]; + bytes4[] memory selectors = facets_[facetIndex].functionSelectors; + // setting the number of selectors + assembly { + mstore(selectors, numSelectors) + } + } + // setting the number of facets + assembly { + mstore(facets_, numFacets) + } + } + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return _facetFunctionSelectors The selectors associated with a facet address. + function facetFunctionSelectors( + address _facet + ) external view override returns (bytes4[] memory _facetFunctionSelectors) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + uint256 numSelectors; + _facetFunctionSelectors = new bytes4[](selectorCount); + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + if (_facet == facetAddress_) { + _facetFunctionSelectors[numSelectors] = selector; + numSelectors++; + } + } + // Set the number of selectors in the array + assembly { + mstore(_facetFunctionSelectors, numSelectors) + } + } + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() + external + view + override + returns (address[] memory facetAddresses_) + { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facetAddresses_ = new address[](selectorCount); + uint256 numFacets; + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + bool continueLoop = false; + // see if we have collected the address already and break out of loop if we have + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facetAddress_ == facetAddresses_[facetIndex]) { + continueLoop = true; + break; + } + } + // continue loop if we already have the address + if (continueLoop) { + continueLoop = false; + continue; + } + // include address + facetAddresses_[numFacets] = facetAddress_; + numFacets++; + } + // Set the number of facet addresses in the array + assembly { + mstore(facetAddresses_, numFacets) + } + } + + /// @notice Gets the facet address that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress( + bytes4 _functionSelector + ) external view override returns (address facetAddress_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + facetAddress_ = ds + .facetAddressAndSelectorPosition[_functionSelector] + .facetAddress; + } + + // This implements ERC-165. + function supportsInterface( + bytes4 _interfaceId + ) external view override returns (bool) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + return ds.supportedInterfaces[_interfaceId]; + } +} diff --git a/contracts/facets/DiamondLoupeFacetNoERC165.sol b/contracts/facets/DiamondLoupeFacetNoERC165.sol new file mode 100644 index 0000000..eee5d5e --- /dev/null +++ b/contracts/facets/DiamondLoupeFacetNoERC165.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +// The functions in DiamondLoupeFacet MUST be added to a diamond. +// The EIP-2535 Diamond standard requires these functions. + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; + +contract DiamondLoupeFacetNoERC165 is IDiamondLoupe { + // Diamond Loupe Functions + //////////////////////////////////////////////////////////////////// + /// These functions are expected to be called frequently by tools. + // + // struct Facet { + // address facetAddress; + // bytes4[] functionSelectors; + // } + /// @notice Gets all facets and their selectors. + /// @return facets_ Facet + function facets() external view override returns (Facet[] memory facets_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facets_ = new Facet[](selectorCount); + // create an array for counting the number of selectors for each facet + uint16[] memory numFacetSelectors = new uint16[](selectorCount); + // total number of facets + uint256 numFacets; + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + bool continueLoop = false; + // find the functionSelectors array for selector and add selector to it + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facets_[facetIndex].facetAddress == facetAddress_) { + facets_[facetIndex].functionSelectors[ + numFacetSelectors[facetIndex] + ] = selector; + numFacetSelectors[facetIndex]++; + continueLoop = true; + break; + } + } + // if functionSelectors array exists for selector then continue loop + if (continueLoop) { + continueLoop = false; + continue; + } + // create a new functionSelectors array for selector + facets_[numFacets].facetAddress = facetAddress_; + facets_[numFacets].functionSelectors = new bytes4[](selectorCount); + facets_[numFacets].functionSelectors[0] = selector; + numFacetSelectors[numFacets] = 1; + numFacets++; + } + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + uint256 numSelectors = numFacetSelectors[facetIndex]; + bytes4[] memory selectors = facets_[facetIndex].functionSelectors; + // setting the number of selectors + assembly { + mstore(selectors, numSelectors) + } + } + // setting the number of facets + assembly { + mstore(facets_, numFacets) + } + } + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return _facetFunctionSelectors The selectors associated with a facet address. + function facetFunctionSelectors( + address _facet + ) external view override returns (bytes4[] memory _facetFunctionSelectors) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + uint256 numSelectors; + _facetFunctionSelectors = new bytes4[](selectorCount); + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + if (_facet == facetAddress_) { + _facetFunctionSelectors[numSelectors] = selector; + numSelectors++; + } + } + // Set the number of selectors in the array + assembly { + mstore(_facetFunctionSelectors, numSelectors) + } + } + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() + external + view + override + returns (address[] memory facetAddresses_) + { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facetAddresses_ = new address[](selectorCount); + uint256 numFacets; + // loop through function selectors + for ( + uint256 selectorIndex; + selectorIndex < selectorCount; + selectorIndex++ + ) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + bool continueLoop = false; + // see if we have collected the address already and break out of loop if we have + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facetAddress_ == facetAddresses_[facetIndex]) { + continueLoop = true; + break; + } + } + // continue loop if we already have the address + if (continueLoop) { + continueLoop = false; + continue; + } + // include address + facetAddresses_[numFacets] = facetAddress_; + numFacets++; + } + // Set the number of facet addresses in the array + assembly { + mstore(facetAddresses_, numFacets) + } + } + + /// @notice Gets the facet address that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress( + bytes4 _functionSelector + ) external view override returns (address facetAddress_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + facetAddress_ = ds + .facetAddressAndSelectorPosition[_functionSelector] + .facetAddress; + } +} diff --git a/contracts/facets/OwnershipFacet.sol b/contracts/facets/OwnershipFacet.sol new file mode 100644 index 0000000..12efcd0 --- /dev/null +++ b/contracts/facets/OwnershipFacet.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; + +contract OwnershipFacet is IERC173 { + function transferOwnership(address _newOwner) external override { + LibDiamond.enforceIsContractOwner(); + LibDiamond.setContractOwner(_newOwner); + } + + function owner() external view override returns (address owner_) { + owner_ = LibDiamond.contractOwner(); + } +} diff --git a/contracts/interfaces/IDiamond.sol b/contracts/interfaces/IDiamond.sol new file mode 100644 index 0000000..bd844ea --- /dev/null +++ b/contracts/interfaces/IDiamond.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +interface IDiamond { + enum FacetCutAction { + Add, + Replace, + Remove + } + // Add=0, Replace=1, Remove=2 + + struct FacetCut { + address facetAddress; + FacetCutAction action; + bytes4[] functionSelectors; + } + + event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); +} diff --git a/contracts/interfaces/IDiamondCut.sol b/contracts/interfaces/IDiamondCut.sol new file mode 100644 index 0000000..bd01085 --- /dev/null +++ b/contracts/interfaces/IDiamondCut.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +import { IDiamond } from "./IDiamond.sol"; + +interface IDiamondCut is IDiamond { + /// @notice Add/replace/remove any number of functions and optionally execute + /// a function with delegatecall + /// @param _diamondCut Contains the facet addresses and function selectors + /// @param _init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments + /// _calldata is executed with delegatecall on _init + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata _calldata + ) external; +} diff --git a/contracts/interfaces/IDiamondLoupe.sol b/contracts/interfaces/IDiamondLoupe.sol new file mode 100644 index 0000000..5e26d62 --- /dev/null +++ b/contracts/interfaces/IDiamondLoupe.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +// A loupe is a small magnifying glass used to look at diamonds. +// These functions look at diamonds +interface IDiamondLoupe { + /// These functions are expected to be called frequently + /// by tools. + + struct Facet { + address facetAddress; + bytes4[] functionSelectors; + } + + /// @notice Gets all facet addresses and their four byte function selectors. + /// @return facets_ Facet + function facets() external view returns (Facet[] memory facets_); + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return facetFunctionSelectors_ + function facetFunctionSelectors( + address _facet + ) external view returns (bytes4[] memory facetFunctionSelectors_); + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() + external + view + returns (address[] memory facetAddresses_); + + /// @notice Gets the facet that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress( + bytes4 _functionSelector + ) external view returns (address facetAddress_); +} diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol new file mode 100644 index 0000000..04b7bcc --- /dev/null +++ b/contracts/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceId The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/contracts/interfaces/IERC173.sol b/contracts/interfaces/IERC173.sol new file mode 100644 index 0000000..90b73cc --- /dev/null +++ b/contracts/interfaces/IERC173.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title ERC-173 Contract Ownership Standard +/// Note: the ERC-165 identifier for this interface is 0x7f5828d0 +/* is ERC165 */ +interface IERC173 { + /// @dev This emits when ownership of a contract changes. + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + /// @notice Get the address of the owner + /// @return owner_ The address of the owner. + function owner() external view returns (address owner_); + + /// @notice Set the address of the new owner of the contract + /// @dev Set _newOwner to address(0) to renounce any ownership. + /// @param _newOwner The address of the new owner of the contract + function transferOwnership(address _newOwner) external; +} diff --git a/contracts/libraries/LibDiamond.sol b/contracts/libraries/LibDiamond.sol new file mode 100644 index 0000000..70dd7cf --- /dev/null +++ b/contracts/libraries/LibDiamond.sol @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ +import { IDiamond } from "../interfaces/IDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; + +// Remember to add the loupe functions from DiamondLoupeFacet to the diamond. +// The loupe functions are required by the EIP2535 Diamonds standard + +error NoSelectorsGivenToAdd(); +error NotContractOwner(address _user, address _contractOwner); +error NoSelectorsProvidedForFacetForCut(address _facetAddress); +error CannotAddSelectorsToZeroAddress(bytes4[] _selectors); +error NoBytecodeAtAddress(address _contractAddress, string _message); +error IncorrectFacetCutAction(uint8 _action); +error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); +error CannotReplaceFunctionsFromFacetWithZeroAddress(bytes4[] _selectors); +error CannotReplaceImmutableFunction(bytes4 _selector); +error CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet( + bytes4 _selector +); +error CannotReplaceFunctionThatDoesNotExists(bytes4 _selector); +error RemoveFacetAddressMustBeZeroAddress(address _facetAddress); +error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector); +error CannotRemoveImmutableFunction(bytes4 _selector); +error InitializationFunctionReverted( + address _initializationContractAddress, + bytes _calldata +); + +library LibDiamond { + bytes32 constant DIAMOND_STORAGE_POSITION = + keccak256("diamond.standard.diamond.storage"); + + struct FacetAddressAndSelectorPosition { + address facetAddress; + uint16 selectorPosition; + } + + struct DiamondStorage { + // function selector => facet address and selector position in selectors array + mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; + bytes4[] selectors; + mapping(bytes4 => bool) supportedInterfaces; + // owner of the contract + address contractOwner; + } + + function diamondStorage() + internal + pure + returns (DiamondStorage storage ds) + { + bytes32 position = DIAMOND_STORAGE_POSITION; + assembly { + ds.slot := position + } + } + + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + function setContractOwner(address _newOwner) internal { + DiamondStorage storage ds = diamondStorage(); + address previousOwner = ds.contractOwner; + ds.contractOwner = _newOwner; + emit OwnershipTransferred(previousOwner, _newOwner); + } + + function contractOwner() internal view returns (address contractOwner_) { + contractOwner_ = diamondStorage().contractOwner; + } + + function enforceIsContractOwner() internal view { + if (msg.sender != diamondStorage().contractOwner) { + revert NotContractOwner(msg.sender, diamondStorage().contractOwner); + } + } + + event DiamondCut( + IDiamondCut.FacetCut[] _diamondCut, + address _init, + bytes _calldata + ); + + // Internal function version of diamondCut + function diamondCut( + IDiamondCut.FacetCut[] memory _diamondCut, + address _init, + bytes memory _calldata + ) internal { + for ( + uint256 facetIndex; + facetIndex < _diamondCut.length; + facetIndex++ + ) { + bytes4[] memory functionSelectors = _diamondCut[facetIndex] + .functionSelectors; + address facetAddress = _diamondCut[facetIndex].facetAddress; + if (functionSelectors.length == 0) { + revert NoSelectorsProvidedForFacetForCut(facetAddress); + } + IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; + if (action == IDiamond.FacetCutAction.Add) { + addFunctions(facetAddress, functionSelectors); + } else if (action == IDiamond.FacetCutAction.Replace) { + replaceFunctions(facetAddress, functionSelectors); + } else if (action == IDiamond.FacetCutAction.Remove) { + removeFunctions(facetAddress, functionSelectors); + } else { + revert IncorrectFacetCutAction(uint8(action)); + } + } + emit DiamondCut(_diamondCut, _init, _calldata); + initializeDiamondCut(_init, _calldata); + } + + function addFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + if (_facetAddress == address(0)) { + revert CannotAddSelectorsToZeroAddress(_functionSelectors); + } + DiamondStorage storage ds = diamondStorage(); + uint16 selectorCount = uint16(ds.selectors.length); + enforceHasContractCode( + _facetAddress, + "LibDiamondCut: Add facet has no code" + ); + for ( + uint256 selectorIndex; + selectorIndex < _functionSelectors.length; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + if (oldFacetAddress != address(0)) { + revert CannotAddFunctionToDiamondThatAlreadyExists(selector); + } + ds.facetAddressAndSelectorPosition[ + selector + ] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount); + ds.selectors.push(selector); + selectorCount++; + } + } + + function replaceFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + DiamondStorage storage ds = diamondStorage(); + if (_facetAddress == address(0)) { + revert CannotReplaceFunctionsFromFacetWithZeroAddress( + _functionSelectors + ); + } + enforceHasContractCode( + _facetAddress, + "LibDiamondCut: Replace facet has no code" + ); + for ( + uint256 selectorIndex; + selectorIndex < _functionSelectors.length; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds + .facetAddressAndSelectorPosition[selector] + .facetAddress; + // can't replace immutable functions -- functions defined directly in the diamond in this case + if (oldFacetAddress == address(this)) { + revert CannotReplaceImmutableFunction(selector); + } + if (oldFacetAddress == _facetAddress) { + revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet( + selector + ); + } + if (oldFacetAddress == address(0)) { + revert CannotReplaceFunctionThatDoesNotExists(selector); + } + // replace old facet address + ds + .facetAddressAndSelectorPosition[selector] + .facetAddress = _facetAddress; + } + } + + function removeFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + DiamondStorage storage ds = diamondStorage(); + uint256 selectorCount = ds.selectors.length; + if (_facetAddress != address(0)) { + revert RemoveFacetAddressMustBeZeroAddress(_facetAddress); + } + for ( + uint256 selectorIndex; + selectorIndex < _functionSelectors.length; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + FacetAddressAndSelectorPosition + memory oldFacetAddressAndSelectorPosition = ds + .facetAddressAndSelectorPosition[selector]; + if (oldFacetAddressAndSelectorPosition.facetAddress == address(0)) { + revert CannotRemoveFunctionThatDoesNotExist(selector); + } + + // can't remove immutable functions -- functions defined directly in the diamond + if ( + oldFacetAddressAndSelectorPosition.facetAddress == address(this) + ) { + revert CannotRemoveImmutableFunction(selector); + } + // replace selector with last selector + selectorCount--; + if ( + oldFacetAddressAndSelectorPosition.selectorPosition != + selectorCount + ) { + bytes4 lastSelector = ds.selectors[selectorCount]; + ds.selectors[ + oldFacetAddressAndSelectorPosition.selectorPosition + ] = lastSelector; + ds + .facetAddressAndSelectorPosition[lastSelector] + .selectorPosition = oldFacetAddressAndSelectorPosition + .selectorPosition; + } + // delete last selector + ds.selectors.pop(); + delete ds.facetAddressAndSelectorPosition[selector]; + } + } + + function initializeDiamondCut( + address _init, + bytes memory _calldata + ) internal { + if (_init == address(0)) { + return; + } + enforceHasContractCode( + _init, + "LibDiamondCut: _init address has no code" + ); + (bool success, bytes memory error) = _init.delegatecall(_calldata); + if (!success) { + if (error.length > 0) { + // bubble up error + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(error) + revert(add(32, error), returndata_size) + } + } else { + revert InitializationFunctionReverted(_init, _calldata); + } + } + } + + function enforceHasContractCode( + address _contract, + string memory _errorMessage + ) internal view { + uint256 contractSize; + assembly { + contractSize := extcodesize(_contract) + } + if (contractSize == 0) { + revert NoBytecodeAtAddress(_contract, _errorMessage); + } + } +} diff --git a/contracts/lit-core/ContractResolver.sol b/contracts/lit-core/ContractResolver.sol new file mode 100644 index 0000000..7405424 --- /dev/null +++ b/contracts/lit-core/ContractResolver.sol @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/access/AccessControl.sol"; + +import "hardhat/console.sol"; + +contract ContractResolver is AccessControl { + /* ========== TYPE DEFINITIONS ========== */ + + // the comments following each one of these are the keccak256 hashes of the string values + // this is very useful if you have to manually set any of these, so that you + // don't have to calculate the hahes yourself. + + bytes32 public constant ADMIN_ROLE = keccak256("ADMIN"); // 0xdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42 + + bytes32 public constant RELEASE_REGISTER_CONTRACT = + keccak256("RELEASE_REGISTER"); // 0x3a68dbfd8bbb64015c42bc131c388dea7965e28c1004d09b39f59500c3a763ec + bytes32 public constant STAKING_CONTRACT = keccak256("STAKING"); // 0x080909c18c958ce5a2d36481697824e477319323d03154ceba3b78f28a61887b + bytes32 public constant STAKING_BALANCES_CONTRACT = + keccak256("STAKING_BALANCES"); // 0xaa06d108dbd7bf976b16b7bf5adb29d2d0ef2c385ca8b9d833cc802f33942d72 + bytes32 public constant MULTI_SENDER_CONTRACT = keccak256("MULTI_SENDER"); // 0xdd5b9b8a5e8e01f2962ed7e983d58fe32e1f66aa88dd7ab30770fa9b77da7243 + bytes32 public constant LIT_TOKEN_CONTRACT = keccak256("LIT_TOKEN"); + bytes32 public constant PUB_KEY_ROUTER_CONTRACT = + keccak256("PUB_KEY_ROUTER"); // 0xb1f79813bc7630a52ae948bc99781397e409d0dd3521953bf7d8d7a2db6147f7 + bytes32 public constant PKP_NFT_CONTRACT = keccak256("PKP_NFT"); // 0xb7b4fde9944d3c13e9a78835431c33a5084d90a7f0c73def76d7886315fe87b0 + bytes32 public constant RATE_LIMIT_NFT_CONTRACT = + keccak256("RATE_LIMIT_NFT"); // 0xb931b2719aeb2a65a5035fa0a190bfdc4c8622ce8cbff7a3d1ab42531fb1a918 + bytes32 public constant PKP_HELPER_CONTRACT = keccak256("PKP_HELPER"); // 0x27d764ea2a4a3865434bbf4a391110149644be31448f3479fd15b44388755765 + bytes32 public constant PKP_HELPER_V2_CONTRACT = keccak256("PKP_HELPER_V2"); // 0x58a0044e0ecd81025e398bf1815075d1234cbac3749614b0b33a404c2ee2babf + bytes32 public constant PKP_PERMISSIONS_CONTRACT = + keccak256("PKP_PERMISSIONS"); // 0x54953c23068b8fc4c0736301b50f10027d6b469327de1fd42841a5072b1bcebe + bytes32 public constant PKP_NFT_METADATA_CONTRACT = + keccak256("PKP_NFT_METADATA"); // 0xf14f431dadc82e7dbc5e379f71234e5735c9187e4327a7c6ac014d55d1b7727a + bytes32 public constant ALLOWLIST_CONTRACT = keccak256("ALLOWLIST"); // 0x74845de37cfabd357633214b47fa91ccd19b05b7c5a08ac22c187f811fb62bca + bytes32 public constant DOMAIN_WALLET_REGISTRY = + keccak256("DOMAIN_WALLET_REGISTRY"); + bytes32 public constant HD_KEY_DERIVER_CONTRACT = + keccak256("HD_KEY_DERIVER"); + bytes32 public constant BACKUP_RECOVERY_CONTRACT = + keccak256("BACKUP_RECOVERY"); + bytes32 public constant PAYMENT_DELEGATION_CONTRACT = + keccak256("PAYMENT_DELEGATION"); // 0xc6674f98ba35c01c130e08195dd26c70466037473a068c5aaa470a783d99c16c + + enum Env { + Dev, + Staging, + Prod + } + + /* ========== ERRORS ========== */ + + /// The ADMIN role is required to use this function + error AdminRoleRequired(); + + /* ========== EVENTS ========== */ + + event AllowedEnvAdded(Env env); + + event AllowedEnvRemoved(Env env); + + event SetContract(bytes32 typ, Env env, address addr); + + /* ========== STATE VARIABLES ========== */ + + mapping(Env => bool) allowedEnvs; + mapping(bytes32 => mapping(Env => address)) public typeAddresses; + + /* ========== CONSTRUCTOR ========== */ + + constructor(Env env) { + _setupRole(ADMIN_ROLE, msg.sender); + _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE); + + allowedEnvs[env] = true; + + emit AllowedEnvAdded(env); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /// add an allowed env + function addAllowedEnv(Env env) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + allowedEnvs[env] = true; + + emit AllowedEnvAdded(env); + } + + /// remove an allowed env + function removeAllowedEnv(Env env) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + delete allowedEnvs[env]; + + emit AllowedEnvRemoved(env); + } + + /// set the active address for a deployed contract + function setContract(bytes32 typ, Env env, address addr) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + // Ensure the env is available + require( + allowedEnvs[env] == true, + "The provided Env is not valid for this contract" + ); + + // Set the contract address + typeAddresses[typ][env] = addr; + + // Emit events + emit SetContract(typ, env, addr); + } + + function addAdmin(address newAdmin) public onlyRole(ADMIN_ROLE) { + _grantRole(ADMIN_ROLE, newAdmin); + } + + function removeAdmin( + address adminBeingRemoved + ) public onlyRole(ADMIN_ROLE) { + require( + adminBeingRemoved != msg.sender, + "Cannot remove self as admin. Have the new admin do it." + ); + _revokeRole(ADMIN_ROLE, adminBeingRemoved); + } + + /* ========== VIEWS ========== */ + + /// Returns the matching contract address for a given type and env + function getContract(bytes32 typ, Env env) public view returns (address) { + return (typeAddresses[typ][env]); + } +} diff --git a/contracts/lit-core/ReleaseRegister.sol b/contracts/lit-core/ReleaseRegister.sol new file mode 100644 index 0000000..278ee81 --- /dev/null +++ b/contracts/lit-core/ReleaseRegister.sol @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/access/AccessControl.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import "hardhat/console.sol"; + +contract ReleaseRegister is AccessControl { + /* ========== DEPS ========== */ + + using EnumerableSet for EnumerableSet.Bytes32Set; + + /* ========== TYPE DEFINITIONS ========== */ + + bytes32 public constant ADMIN_ROLE = keccak256("ADMIN"); + bytes32 public constant CREATOR_ROLE = keccak256("CREATOR"); + bytes32 public constant ACTIVATOR_ROLE = keccak256("ACTIVATOR"); + bytes32 public constant DEACTIVATOR_ROLE = keccak256("DEACTIVATOR"); + bytes32 public constant BURNER_ROLE = keccak256("BURNER"); + + // Also update contracts/release/mod.rs + uint public constant RELEASE_OPTION_RO = 1 << 1; + uint public constant RELEASE_OPTION_USERS = 1 << 2; + uint public constant RELEASE_OPTION_SSH = 1 << 3; + + enum Status { + Null, + Pending, + Active, + Disabled + } + + enum Env { + Dev, + Staging, + Prod + } + + enum Type { + Node, + Prov, + Build, + Custom + } + + enum Platform { + MetalAmdSev + } + + struct Release { + Status status; + Env env; + Type typ; + bytes kind; + uint date; + Platform platform; + uint options; + bytes id_key_digest; + bytes public_key; + bytes cid; + } + + /* ========== ERRORS ========== */ + + /// A release with this ID does not exist. + error ReleaseNotFound(); + + /// The env provided is not valid for this contract.. + error InvalidEnv(); + + /// The status provided is not valid in this context. + error InvalidStatus(); + + /// The ADMIN role is required to use this function + error AdminRoleRequired(); + + /// The CREATOR role is required to use this function + error CreatorRoleRequired(); + + /// The ACTIVATOR role is required when setting status to Active + error ActivatorRoleRequired(); + + /// The DEACTIVATOR role is required when setting status to Disabled + error DeactivatorRoleRequired(); + + /// The BURNER role is required when burning a release + error BurnerRoleRequired(); + + /* ========== EVENTS ========== */ + + event InitCreator(bytes domain, bytes authorKeyDigest); + + event AllowedEnvAdded(Env env); + + event AllowedEnvRemoved(Env env); + + event AllowedSubnetAdded(address subnet); + + event AllowedSubnetRemoved(address subnet); + + event AllowedAdminSigningPublicKeyAdded(bytes pubKey); + + event AllowedAdminSigningPublicKeyRemoved(bytes pubKey); + + event AllowedAuthorKeyDigestAdded(bytes digest); + + event AllowedAuthorKeyDigestRemoved(bytes digest); + + event ReleaseCreated( + bytes32 releaseId, + Status status, + Env env, + Type typ, + bytes kind, + uint date, + Platform platform, + uint options, + bytes id_key_digest, + bytes public_key, + bytes cid + ); + + event ReleaseStatusChange(bytes32 releaseId, Status status); + + event ReleaseBurned(bytes32 releaseId); + + /* ========== STATE VARIABLES ========== */ + + bool creatorInit; + bytes creatorDomain; + mapping(Env => bool) allowedEnvs; + mapping(address => bool) allowedSubnets; + mapping(bytes => bool) allowedAdminSigningPublicKeys; + mapping(bytes => bool) allowedAuthorKeyDigests; + mapping(bytes32 => Release) releases; + mapping(bytes32 => bytes32) activeReleases; + EnumerableSet.Bytes32Set activeReleaseSet; + + /* ========== CONSTRUCTOR ========== */ + + constructor(Env env) { + _setupRole(ADMIN_ROLE, msg.sender); + _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE); + _setRoleAdmin(CREATOR_ROLE, ADMIN_ROLE); + _setRoleAdmin(ACTIVATOR_ROLE, ADMIN_ROLE); + _setRoleAdmin(DEACTIVATOR_ROLE, ADMIN_ROLE); + _setRoleAdmin(BURNER_ROLE, ADMIN_ROLE); + + allowedEnvs[env] = true; + + emit AllowedEnvAdded(env); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /// initialise the creator portion of the contract (provisioning). + function initCreator( + Env env, + address subnetId, + bytes memory domain, + bytes memory authorKeyDigest + ) public { + // Check roles + if (!hasRole(CREATOR_ROLE, msg.sender)) { + revert CreatorRoleRequired(); + } + + // Ensure the env is allowed + if (allowedEnvs[env] != true) { + revert InvalidEnv(); + } + + if (env != Env.Dev && env != Env.Staging) { + require(!creatorInit, "initCreator() may only be called once"); + } + + creatorInit = true; + creatorDomain = domain; + + allowedSubnets[subnetId] = true; + allowedAuthorKeyDigests[authorKeyDigest] = true; + + emit AllowedAuthorKeyDigestAdded(authorKeyDigest); + emit AllowedSubnetAdded(subnetId); + emit InitCreator(domain, authorKeyDigest); + } + + /// add an allowed env + function addAllowedEnv(Env env) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + allowedEnvs[env] = true; + + emit AllowedEnvAdded(env); + } + + /// remove an allowed env + function removeAllowedEnv(Env env) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + delete allowedEnvs[env]; + + emit AllowedEnvRemoved(env); + } + + /// add an allowed subnet + function addAllowedSubnet(address subnet) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + allowedSubnets[subnet] = true; + + emit AllowedSubnetAdded(subnet); + } + + /// remove an allowed subnet + function removeAllowedSubnet(address subnet) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + delete allowedSubnets[subnet]; + + emit AllowedSubnetRemoved(subnet); + } + + /// add an admin signing public key + function addAllowedAdminSigningPublicKey(bytes memory pubKey) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + allowedAdminSigningPublicKeys[pubKey] = true; + + emit AllowedAdminSigningPublicKeyAdded(pubKey); + } + + /// remove an admin signing public key + function removeAllowedAdminSigningPublicKey(bytes memory pubKey) public { + // Check roles + if (!hasRole(ADMIN_ROLE, msg.sender)) { + revert AdminRoleRequired(); + } + + delete allowedAdminSigningPublicKeys[pubKey]; + + emit AllowedAdminSigningPublicKeyRemoved(pubKey); + } + + /// create a release + function updateActiveRelease(bytes32 releaseId) internal virtual { + // Ensure it exists + if (releases[releaseId].status == Status.Null) { + revert ReleaseNotFound(); + } + + Release memory release = releases[releaseId]; + + // Ensure it's active. + if (release.status != Status.Active) { + revert InvalidStatus(); + } + + bytes32 activeHashKey = keccak256( + abi.encodePacked( + release.env, + release.typ, + release.kind, + release.platform + ) + ); + bytes32 currentActiveId = activeReleases[activeHashKey]; + + if (currentActiveId != 0) { + if (release.date > releases[currentActiveId].date) { + activeReleases[activeHashKey] = releaseId; + } + } else { + activeReleases[activeHashKey] = releaseId; + } + + // Add to set + activeReleaseSet.add(releaseId); + } + + /// create a release + function createRelease( + bytes32 releaseId, + Status status, + Env env, + Type typ, + bytes memory kind, + Platform platform, + uint options, + bytes memory id_key_digest, + bytes memory public_key, + bytes memory cid, + uint date + ) public { + // Check roles + if (!hasRole(CREATOR_ROLE, msg.sender)) { + revert CreatorRoleRequired(); + } + + if (status == Status.Active) { + if (!hasRole(ACTIVATOR_ROLE, msg.sender)) { + revert ActivatorRoleRequired(); + } + } else if (status != Status.Pending && status != Status.Disabled) { + revert InvalidStatus(); + } + + // Ensure the env is allowed + if (allowedEnvs[env] != true) { + revert InvalidEnv(); + } + + // Ensure the subnet is allowed + require( + allowedSubnets[_extractAddressFromBytes32(releaseId, 4)] == true, + "The provided subnet (within the release id) is not valid for this contract" + ); + + if (env != Env.Dev && env != Env.Staging) { + // Ensure does not already exist + require( + releases[releaseId].status == Status.Null, + "A release with this ID already exists" + ); + } + + // Check options + if (env == Env.Prod) { + require( + (options & RELEASE_OPTION_RO) != 0, + "The RO option is required for prod releases" + ); + } + + // Add the new release + if (date == 0) { + date = block.timestamp; + } + + releases[releaseId] = Release( + status, + env, + typ, + kind, + date, + platform, + options, + id_key_digest, + public_key, + cid + ); + + // Emit events + emit ReleaseCreated( + releaseId, + status, + env, + typ, + kind, + date, + platform, + options, + id_key_digest, + public_key, + cid + ); + + if (status == Status.Active) { + updateActiveRelease(releaseId); + + emit ReleaseStatusChange(releaseId, status); + } + } + + /// set the release status + function setReleaseStatus(bytes32 releaseId, Status status) public { + // Check roles + if (status == Status.Active) { + if (!hasRole(ACTIVATOR_ROLE, msg.sender)) { + revert ActivatorRoleRequired(); + } + } else if (status == Status.Disabled) { + if (!hasRole(DEACTIVATOR_ROLE, msg.sender)) { + revert DeactivatorRoleRequired(); + } + } else { + revert InvalidStatus(); + } + + // Ensure it exists + if (releases[releaseId].status == Status.Null) { + revert ReleaseNotFound(); + } + + // Ensure status can be changed + Release memory release = releases[releaseId]; + + if (status != Status.Active) { + require( + getActiveRelease( + release.env, + release.typ, + release.kind, + release.platform + ) != releaseId, + "Must replace active release before changing status from Active" + ); + } + + // Update the status + releases[releaseId].status = status; + + // Emit events + emit ReleaseStatusChange(releaseId, status); + + // Update active release + if (status == Status.Active) { + updateActiveRelease(releaseId); + } else { + activeReleaseSet.remove(releaseId); + } + } + + /// burn a release + function burnRelease(bytes32 releaseId) public { + // Check roles + + if (!hasRole(BURNER_ROLE, msg.sender)) { + revert BurnerRoleRequired(); + } + + // Ensure it exists + if (releases[releaseId].status == Status.Null) { + revert ReleaseNotFound(); + } + + // Delete + delete releases[releaseId]; + activeReleaseSet.remove(releaseId); + + // Emit events + emit ReleaseBurned(releaseId); + } + + /* ========== VIEWS ========== */ + + /// Check if the creator init method has been called. + function hasCreatorInit() external view returns (bool) { + return (creatorInit); + } + + /// Get the creator (provisioning) domain. + function getCreatorDomain() external view returns (bytes memory) { + return (creatorDomain); + } + + /// Check if has allowed env. + function hasAllowedEnv(Env env) external view returns (bool) { + return (allowedEnvs[env]); + } + + /// Check if has allowed subnet. + function hasAllowedSubnet(address subnet) external view returns (bool) { + return (allowedSubnets[subnet]); + } + + /// Check if has allowed author key digest. + function hasAllowedAuthorKeyDigest( + bytes memory digest + ) external view returns (bool) { + return (allowedAuthorKeyDigests[digest]); + } + + /// Check if has allowed admin signing public key. + function hasAllowedAdminSigningPublicKey( + bytes memory pubKey + ) external view returns (bool) { + return (allowedAdminSigningPublicKeys[pubKey]); + } + + /// Returns the release for a given id. + function getRelease( + bytes32 releaseId + ) external view returns (Release memory) { + return releases[releaseId]; + } + + /// Returns the active release for a given criteria. + function getActiveRelease( + Env env, + Type typ, + bytes memory kind, + Platform platform + ) public view returns (bytes32) { + bytes32 activeHashKey = keccak256( + abi.encodePacked(env, typ, kind, platform) + ); + + return (activeReleases[activeHashKey]); + } + + /// Returns the active releases. + function getActiveReleases() public view returns (bytes32[] memory) { + return (activeReleaseSet.values()); + } + + /* ========== UTILS ========== */ + + function _extractAddressFromBytes32( + bytes32 input, + uint offset + ) private pure returns (address) { + bytes32 out; + + for (uint i = 0; i < 20; i++) { + out |= bytes32(input[offset + i] & 0xFF) >> (i * 8); + } + + return address(uint160(bytes20(out))); + } +} diff --git a/contracts/Allowlist.sol b/contracts/lit-node/Allowlist.sol similarity index 100% rename from contracts/Allowlist.sol rename to contracts/lit-node/Allowlist.sol diff --git a/contracts/lit-node/BackupRecovery.sol b/contracts/lit-node/BackupRecovery.sol new file mode 100644 index 0000000..4f082f0 --- /dev/null +++ b/contracts/lit-node/BackupRecovery.sol @@ -0,0 +1,88 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { IPubkeyRouter } from "../lit-node/PubkeyRouter/LibPubkeyRouterStorage.sol"; +import { Staking } from "../lit-node/Staking.sol"; +import { StakingViewsFacet } from "./Staking/StakingViewsFacet.sol"; +import { LibStakingStorage } from "./Staking/LibStakingStorage.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { LibBackupRecoveryStorage } from "./BackupRecovery/LibBackupRecoveryStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct BackupRecoveryArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract BackupRecovery { + /* ========== CONSTRUCTOR ========== */ + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + BackupRecoveryArgs memory _args + ) { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + ContractResolver resolver = ContractResolver(_args.contractResolver); + LibBackupRecoveryStorage.getStorage().resolver = resolver; + LibBackupRecoveryStorage.getStorage().env = _args.env; + // Current verification version: 1 + LibBackupRecoveryStorage.getStorage().verificationVersion = bytes1( + 0x01 + ); + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/BackupRecovery/BackupRecoveryFacet.sol b/contracts/lit-node/BackupRecovery/BackupRecoveryFacet.sol new file mode 100644 index 0000000..cbdbbd4 --- /dev/null +++ b/contracts/lit-node/BackupRecovery/BackupRecoveryFacet.sol @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { LibBackupRecoveryStorage } from "./LibBackupRecoveryStorage.sol"; +import { StakingViewsFacet } from "../Staking/StakingViewsFacet.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import "hardhat/console.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +contract BackupRecoveryFacet { + address public constant BASE_EC_OP_ADDRESS = + 0x000000000000000000000000000000000000012D; + bytes32 HASH_SHA2_256 = sha256("sha2-256"); + + // errors + error CallerNotOwner(); + error BackupStateAlreadyRegistered(bytes pubkey); + error NodesAllMappedToBackupMembers(address addr); + error BackupStateNotRegistered(); + error InvalidCaller(address addr); + error BackupMemberNotMappedToNode(address peer); + error BackupKeysMismatch( + bytes publicKey, + bytes senderPublicKey, + bytes blsKey, + bytes senderBlsKey + ); + error BackupSetIncomplete(address[] members); + error WrongVerificationVersion(); + error ProofExpired(); + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + function s() + internal + pure + returns (LibBackupRecoveryStorage.BackupRecoveryStorage storage) + { + return LibBackupRecoveryStorage.getStorage(); + } + + function _calculatePartyThreshold() public view returns (uint256) { + if (s().nextState[0].partyMembers.length == 2) { + return 2; + } + return (s().nextState[0].partyMembers.length * 2) / 3; + } + + function _getStakingViewFacet() public view returns (StakingViewsFacet) { + address stakingAddress = s().resolver.getContract( + s().resolver.STAKING_CONTRACT(), + s().env + ); + return StakingViewsFacet(stakingAddress); + } + + function _checkValidatorSetForAddress( + address sender + ) public view returns (bool) { + address[] memory validators = _getStakingViewFacet() + .getValidatorsInCurrentEpoch(); + address stakerAddressOfSender = _getStakingViewFacet() + .nodeAddressToStakerAddress(sender); + + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i] == stakerAddressOfSender) { + return true; + } + } + + return false; + } + + function _checkBackupSetForSender( + address sender + ) internal view returns (bool) { + for (uint256 i = 0; i < s().nextState[0].partyMembers.length; i++) { + if (sender == s().nextState[0].partyMembers[i]) { + return true; + } + } + + return false; + } + + function _updateRecoveryState() internal { + s().recoveryState[0].secp256K1EcdsaPubKey = s().nextState[0].pubkey; + s().recoveryState[0].bls12381G1EncKey = s() + .nextState[0] + .encryptedBlsKey; + s().recoveryState[0].partyThreshold = _calculatePartyThreshold(); + s().recoveryState[0].sessionId = s().nextState[0].sessionId; + s().recoveryState[0].partyMembers = s().nextState[0].partyMembers; + + _deleteNextStateMappings(); + delete s().nextState[0]; + } + + function _schnorr_verify_1( + bytes memory input + ) internal view returns (bool, bytes memory) { + (bool success, bytes memory res) = BASE_EC_OP_ADDRESS.staticcall(input); + + return (success, res); + } + + /** + * @dev + * Returns the currrent recovery party state + * If not all backup party members register their state the struct will be null + */ + function getBackupPartyState() + public + view + returns (LibBackupRecoveryStorage.BackupRecoveryState memory) + { + return s().recoveryState[0]; + } + + /** + * @dev + * Get the next set of backup party members. + * if looking for the current set the `getBackupPartyState` + * contains the current backup party members + */ + function getNextBackupPartyMembers() + public + view + returns (address[] memory backupMembers) + { + return s().nextState[0].partyMembers; + } + + /** + * @dev + * get the state of a backup from a previous set of backup party members + * sessionId is used for looking up the historic state. + * If called before the state is made the non active state it will return a null struct + * to get the most recent state use `getBackupPartyState` + */ + function getPastBackupState( + bytes memory sessionId + ) + public + view + returns (LibBackupRecoveryStorage.BackupRecoveryState memory partyState) + { + return s().pastBackupStates[sessionId]; + } + + function getNextBackupState() + public + view + returns ( + LibBackupRecoveryStorage.NextStateDownloadable memory nextState + ) + { + return + LibBackupRecoveryStorage.NextStateDownloadable( + s().nextState[0].partyMembers, + s().nextState[0].registeredRecoveryKeys + ); + } + + /** + * @dev + * Returns the count of party members needed to perform recovery + */ + function getDecryptionThreshold() public view returns (uint256) { + return _calculatePartyThreshold(); + } + + function recieveProofsK256( + bytes calldata proof + ) public view returns (bool) { + address sender = msg.sender; + require( + _checkBackupSetForSender(sender), + "BackupRecovery: Sender is not a party member" + ); + + (bool ecdsaSuccess, bytes memory ecdsaRes) = _schnorr_verify_1(proof); + + return ecdsaSuccess; + } + + /** + * @dev + * Verifies the encoded schnorr proof for BLS 12381G1 curve type + * utilizes a precompile for bls schnorr verification + * if the proof is valid we map the proofs recieved to the back up party member which submitted it + */ + function recieveProofBls12381G1( + bytes calldata proof + ) public returns (bool) { + address sender = msg.sender; + require( + _checkBackupSetForSender(sender), + "BackupRecovery: Sender is not a party member" + ); + + bytes1 version = bytes1(proof[0]); + if (version != s().verificationVersion) { + revert WrongVerificationVersion(); + } + + // encoding format + // Version || Timestamp || ParticipantId || Curve || SchnorrProof || SchnorrVerificationKey + uint64 timestamp = uint64(bytes8(proof[1:9])); + bytes32 crv = bytes32(proof[10:42]); + bytes memory sProof = bytes(proof[42:170]); + bytes memory sKey = bytes(proof[170:266]); + bytes32 hName = HASH_SHA2_256; + bytes32 y = sha256(proof[0:42]); + bytes1 op = 0x51; // bls schnorr_verify_1 + + bytes memory pcProof = abi.encodePacked( + op, + crv, + hName, + y, + sKey, + sProof + ); + + (bool blsSuccess, bytes memory blsRes) = _schnorr_verify_1(pcProof); + + // If the precompile status is true and the byte returned is 1 we have verification of the proof + // If the byte retuirned is 0 then we know the proof verification has failed + // if the success boolean is false then we know that the precompile had an error returned and was not successful + if (blsSuccess && bytes1(blsRes) == 0x01) { + if (s().submittedProofs[sender].length < 1) { + s().submittedProofs[sender] = new uint256[](2); + s().submittedProofs[sender][0] = timestamp; + } else if (s().submittedProofs[sender].length < 3) { + s().submittedProofs[sender][1] = timestamp; + } + + return true; + } + + return false; + } + + function getProofSubmissionForBackupPartyMember() + public + view + returns (uint256) + { + address sender = msg.sender; + require( + _checkBackupSetForSender(sender), + "BackupRecovery: Sender is not a party member" + ); + return s().submittedProofs[sender].length; + } + + /** + * @dev + * Registers a set of bls and ecdsa keys for a given party member based on the sender address + * Creates a backup recovery snapshot with the two respective keys + * which is incomplete until all recovery signatures are registered to chain + */ + function recieveNewKeySet( + bytes memory publicKey, + bytes memory encryptedKey, + bytes memory sessionId + ) public { + address sender = msg.sender; + require( + _checkBackupSetForSender(sender), + "BackupRecovery: Sender is not a party member" + ); + + // condition checks if the current set of public keys matches what is held in + // the next state for the backup. If they do not match we set the next state + // public keys to what is submitted by the backup party member + // byte comparison is not supported between memory and storage + // so we encode and hash to compare 32 byte hashes + if ( + keccak256(abi.encodePacked(publicKey)) == + keccak256(abi.encodePacked(s().nextState[0].pubkey)) + ) { + s().nextState[0].keysRecieved[msg.sender] = true; + for (uint256 i = 0; i < s().nextState[0].partyMembers.length; i++) { + if ( + s().nextState[0].keysRecieved[ + s().nextState[0].partyMembers[i] + ] != true + ) { + return; + } + } + + // make nextState backupState + _updateRecoveryState(); + emit BackupKeysRegistered(s().recoveryState[0]); + } else { + // length check for null if null set the state + // otherwise we reject the transaction as there is a lack of consensus + if (s().nextState[0].pubkey.length < 1) { + s().nextState[0].pubkey = publicKey; + s().nextState[0].encryptedBlsKey = encryptedKey; + s().nextState[0].sessionId = sessionId; + s().nextState[0].keysRecieved[msg.sender] = true; + } else { + // revert as the there is a key mismatch and not the first sender + revert BackupKeysMismatch( + s().nextState[0].pubkey, + publicKey, + s().nextState[0].encryptedBlsKey, + encryptedKey + ); + } + } + } + + /** + * @dev + * Resets the contract state by registering a new set of backup members + * emits `BackupPartyRegistered` + */ + function registerNewBackupParty( + address[] memory partyMembers + ) public onlyOwner { + require( + partyMembers.length > 1, + "BackupRecovery: cannot vote for empty party set" + ); + + // record the past state for history + s().pastBackupStates[s().recoveryState[0].sessionId] = s() + .recoveryState[0]; + + // null the recoveryState and public key state + delete s().recoveryState[0]; + + // clear the next state to start over + _deleteNextStateMappings(); + delete s().nextState[0]; + + s().nextState[0].partyMembers = partyMembers; + s().nextState[0].nodesAssignedCount = 0; + + emit BackupPartyRegistered(_calculatePartyThreshold()); + } + + function _deleteNextStateMappings() internal { + address[] memory oldPartyMembers = s().nextState[0].partyMembers; + for (uint256 i = 0; i < oldPartyMembers.length; i++) { + address oldPartyMember = oldPartyMembers[i]; + address oldPeer = s().nextState[0].backupMemberPeerMapping[ + oldPartyMember + ]; + + delete s().nextState[0].backupMemberPeerMapping[oldPartyMember]; + delete s().nextState[0].peerToBackupMemberMapping[oldPeer]; + delete s().nextState[0].keysRecieved[oldPartyMember]; + delete s().submittedProofs[oldPartyMember]; + // No need to delete `votesToRegisterRecoveryKeys` as the pubKey will be different for all the DKGs + } + } + + /** + * @dev + * @helper + * Returns whether all the Backup members have been mapped to a node operator + */ + function allBackupMembersMapped() public view returns (bool mapped) { + return + s().nextState[0].partyMembers.length == + s().nextState[0].nodesAssignedCount; + } + + /** + * @dev + * @helper + * Helper function to check whether the current Recovery DKG has completed successfully + */ + function isRecoveryDkgCompleted() public view returns (bool) { + return s().nextState[0].registeredRecoveryKeys.length > 0; + } + + /** + * @dev + * Vote to register Recovery pubKeys + * msg.sender is the nodeAddress + */ + function registerRecoveryKeys( + LibBackupRecoveryStorage.RecoveryKey[] memory recoveryKeys + ) public { + require( + s().nextState[0].partyMembers.length > 1, + "BackupRecovery: cannot do dkg for empty party set" + ); + + require( + s().nextState[0].peerToBackupMemberMapping[msg.sender] != + address(0), + "BackupRecovery: not a member of the Recovery DKG peer group" + ); + + require( + s().nextState[0].registeredRecoveryKeys.length == 0, + "BackupRecovery: recovery keys already set for this Recovery DKG" + ); + + // record the votes + for (uint i = 0; i < recoveryKeys.length; i++) { + LibBackupRecoveryStorage.RecoveryKey + memory recoveryKey = recoveryKeys[i]; + + require( + s() + .nextState[0] + .votesToRegisterRecoveryKeys[recoveryKey.pubkey] + .voted[msg.sender] == false, + "BackupRecovery: validator has already voted for this recovery key" + ); + + s() + .nextState[0] + .votesToRegisterRecoveryKeys[recoveryKey.pubkey] + .votes += 1; + s() + .nextState[0] + .votesToRegisterRecoveryKeys[recoveryKey.pubkey] + .voted[msg.sender] = true; + + // If all the Recovery peers have voted, register it + if ( + s() + .nextState[0] + .votesToRegisterRecoveryKeys[recoveryKey.pubkey] + .votes == s().nextState[0].partyMembers.length + ) { + s().nextState[0].registeredRecoveryKeys.push(recoveryKey); + + emit RecoveryKeySet(recoveryKey); + } + } + } + + /** + * @dev + * Maps a backup party member to a validator node. returns the address of the mapped validator + * Validator refers to a node operator in this contenxt. + * msg.sender is the nodeAddress + */ + function setMemberForDkg() public returns (address bp) { + require( + _checkValidatorSetForAddress(msg.sender), + "BackupRecovery: not a member of the current peer group" + ); + if (allBackupMembersMapped()) { + // Also checks whether backup party exists + revert NodesAllMappedToBackupMembers(msg.sender); + } + if ( + s().nextState[0].peerToBackupMemberMapping[msg.sender] != address(0) + ) { + return s().nextState[0].peerToBackupMemberMapping[msg.sender]; + } + + s().nextState[0].peerToBackupMemberMapping[msg.sender] = s() + .nextState[0] + .partyMembers[s().nextState[0].nodesAssignedCount]; + s().nextState[0].backupMemberPeerMapping[ + s().nextState[0].partyMembers[s().nextState[0].nodesAssignedCount] + ] = msg.sender; + s().nextState[0].nodesAssignedCount += 1; + emit NodeAssignedToBackupMember( + s().nextState[0].peerToBackupMemberMapping[msg.sender], + msg.sender + ); + + return s().nextState[0].peerToBackupMemberMapping[msg.sender]; + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + s().resolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); + } + + /** + * @dev + * returns the mapped backup party member to a member of the peer set + * this peer will contain the backup party members key share from dkg + * msg.sender is the nodeAddress + */ + function getMemberForNodeDkg() public view returns (address bp) { + return s().nextState[0].peerToBackupMemberMapping[msg.sender]; + } + + /** + * @dev + * get a peer address for a given backup party members key share. + * the returned address will contain it's backup share + * you can look up the wallet address in the peer state. + */ + function getNodeForBackupMember() public view returns (address peer) { + address sender = msg.sender; + require( + _checkBackupSetForSender(sender), + "BackupRecovery: Sender is not a party member" + ); + + return s().nextState[0].backupMemberPeerMapping[msg.sender]; + } + + /** + * @dev + * @helper + * returns a boolean value relating to if a node is part of the dkg set + * msg.sender is the nodeAddress + */ + function isNodeForDkg() public view returns (bool inSet) { + if ( + s().nextState[0].peerToBackupMemberMapping[msg.sender] != address(0) + ) { + return true; + } + + return false; + } + + /** + * @dev + * @helper + * after mapping of nodes for dkg this can be used as a helper method to get all node addresses for the dkg operation + * these then can be used to look up the `validatorStruct` in the staking contract + * If called before all party members have been mapped to a node for dkg the set will be incomplete. + * Correct set size can be validated by comparing with the backup recovery party state. + */ + function getNodeAddressesForDkg() + public + view + returns (address[] memory nodes) + { + require( + _checkValidatorSetForAddress(msg.sender), + "BackupRecovery: not a member of the current peer group" + ); + + address[] memory nodeAddresses = new address[]( + s().nextState[0].partyMembers.length + ); + + for (uint256 i = 0; i < s().nextState[0].partyMembers.length; i++) { + nodeAddresses[i] = s().nextState[0].backupMemberPeerMapping[ + s().nextState[0].partyMembers[i] + ]; + + if (nodeAddresses[i] == address(0)) { + revert BackupSetIncomplete(nodeAddresses); + } + } + + return nodeAddresses; + } + + /** + * @dev + * @helper + * after mapping of nodes for dkg this can be used as a helper method to get all node addresses for the dkg operation + * these then can be used to look up the `validatorStruct` in the staking contract + * If called before all party members have been mapped to a node for dkg the set will be incomplete. + * Correct set size can be validated by comparing with the backup recovery party state. + */ + function getStakerAddressesForDkg() + public + view + returns (address[] memory nodes) + { + address[] memory stakerAddresses = new address[]( + s().nextState[0].partyMembers.length + ); + + for (uint256 i = 0; i < s().nextState[0].partyMembers.length; i++) { + address nodeAddress = s().nextState[0].backupMemberPeerMapping[ + s().nextState[0].partyMembers[i] + ]; + + if (nodeAddress == address(0)) { + revert BackupSetIncomplete(stakerAddresses); + } + + stakerAddresses[i] = _getStakingViewFacet() + .nodeAddressToStakerAddress(nodeAddress); + } + + return stakerAddresses; + } + + /* ========== EVENTS ========== */ + + /** + * + * Emits when a new backup party is registered, after the inital + */ + event BackupPartyRegistered(uint256 partyTheshold); + + /** + * Emits when keys are reigstered from all parties in the backup set + */ + event BackupKeysRegistered( + LibBackupRecoveryStorage.BackupRecoveryState state + ); + + /** + * Emits when a node is assigned to a backup member for dkg + */ + event NodeAssignedToBackupMember( + address backupMemberAddress, + address NodeAddress + ); + + /** + * Emits when a recovery key has been registered for the current Recovery DKG + */ + event RecoveryKeySet(LibBackupRecoveryStorage.RecoveryKey recoveryKey); + + /** + * Emits when the contract resolver address is set + */ + event ContractResolverAddressSet(address newResolverAddress); +} diff --git a/contracts/lit-node/BackupRecovery/BackupRecoveryNodeStatusFacet.sol b/contracts/lit-node/BackupRecovery/BackupRecoveryNodeStatusFacet.sol new file mode 100644 index 0000000..28eac3b --- /dev/null +++ b/contracts/lit-node/BackupRecovery/BackupRecoveryNodeStatusFacet.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { LibBackupRecoveryStorage } from "./LibBackupRecoveryStorage.sol"; +import { StakingViewsFacet } from "./../Staking/StakingViewsFacet.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import "hardhat/console.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +contract BackupRecoveryNodeStatusFacet { + uint256 public constant CURRENT = 0; + + function s() + internal + pure + returns (LibBackupRecoveryStorage.BackupRecoveryStorage storage) + { + return LibBackupRecoveryStorage.getStorage(); + } + + /** + * @dev + * Registers the status of the node + */ + function setNodeRecoveryStatus( + LibBackupRecoveryStorage.NodeRecoveryStatus status + ) external { + require( + checkValidatorSetForAddress(msg.sender), + "BackupRecovery: not a member of the validator set" + ); + + for (uint256 i = 0; i < s().nodeStatusMap[CURRENT].length; i++) { + if (s().nodeStatusMap[CURRENT][i].node_address == msg.sender) { + s().nodeStatusMap[CURRENT][i].status = status; + return; + } + } + + s().nodeStatusMap[CURRENT].push( + LibBackupRecoveryStorage.NodeRecoveryStatusMap(msg.sender, status) + ); + } + + /** + * @dev + * Reports the recovery status of the nodes + */ + function getNodeRecoveryStatus() + external + view + returns (LibBackupRecoveryStorage.NodeRecoveryStatusMap[] memory) + { + return s().nodeStatusMap[CURRENT]; + } + + /** + * @dev + * Clears the recovery status of the nodes after the recovery + */ + function clearNodeRecoveryStatus() external { + require( + msg.sender == LibDiamond.contractOwner(), + "BackupRecovery: caller not the admin" + ); + + delete s().nodeStatusMap[CURRENT]; + } + + function getStakingViewFacet() internal view returns (StakingViewsFacet) { + address stakingAddress = s().resolver.getContract( + s().resolver.STAKING_CONTRACT(), + s().env + ); + return StakingViewsFacet(stakingAddress); + } + + function checkValidatorSetForAddress( + address sender + ) internal view returns (bool) { + address[] memory validators = getStakingViewFacet() + .getValidatorsInCurrentEpoch(); + + for (uint256 i = 0; i < validators.length; i++) { + address stakerAddressOfSender = getStakingViewFacet() + .nodeAddressToStakerAddress(sender); + if (validators[i] == stakerAddressOfSender) { + return true; + } + } + + return false; + } +} diff --git a/contracts/lit-node/BackupRecovery/BackupRecoveryTestFacet.sol b/contracts/lit-node/BackupRecovery/BackupRecoveryTestFacet.sol new file mode 100644 index 0000000..1d22345 --- /dev/null +++ b/contracts/lit-node/BackupRecovery/BackupRecoveryTestFacet.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { LibBackupRecoveryStorage } from "./LibBackupRecoveryStorage.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import "hardhat/console.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +contract BackupRecoveryTestFacet { + function s() + internal + pure + returns (LibBackupRecoveryStorage.BackupRecoveryStorage storage) + { + return LibBackupRecoveryStorage.getStorage(); + } + + /** + * @dev + * Sets the contract state by registering a new set of backup members + */ + function setBackupPartyState( + bytes calldata bls12381G1EncKey, + bytes calldata secp256K1EcdsaPubKey, + address[] calldata partyMembers + ) public { + require( + partyMembers.length > 1, + "BackupRecovery: cannot vote for empty party set" + ); + + // Set a mock state + s().recoveryState[0].bls12381G1EncKey = bls12381G1EncKey; + s().recoveryState[0].secp256K1EcdsaPubKey = secp256K1EcdsaPubKey; + if (partyMembers.length == 2) { + s().recoveryState[0].partyThreshold = 2; + } else { + s().recoveryState[0].partyThreshold = (partyMembers.length * 2) / 3; + } + s().recoveryState[0].sessionId = "Test_session_id"; + s().recoveryState[0].partyMembers = partyMembers; + } +} diff --git a/contracts/lit-node/BackupRecovery/BackupRecoveryViewFacet.sol b/contracts/lit-node/BackupRecovery/BackupRecoveryViewFacet.sol new file mode 100644 index 0000000..9de4274 --- /dev/null +++ b/contracts/lit-node/BackupRecovery/BackupRecoveryViewFacet.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT + +import { LibBackupRecoveryStorage } from "./LibBackupRecoveryStorage.sol"; +import { StakingViewsFacet } from "./../Staking/StakingViewsFacet.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +contract BackupRecoveryViewFacet { + function getNonSubmitingBackupMembersInNextState() + public + view + returns (address[] memory missingRecoveryMembers) + { + LibBackupRecoveryStorage.NextState + storage nextState = LibBackupRecoveryStorage.getStorage().nextState[ + 0 + ]; + + // Alloc the size of the whole backup party set on the stack + // this allows us to not use sotrage and keep the method view + // the returned array will contained zeroized elements for the indexes in + // the array which map to the parties position in their storage array. + address[] memory nonRegisteredPartyMembers = new address[]( + nextState.partyMembers.length + ); + for (uint256 i = 0; i < nextState.partyMembers.length; i++) { + if (!nextState.keysRecieved[nextState.partyMembers[i]]) { + nonRegisteredPartyMembers[i] = nextState.partyMembers[i]; + } + } + + return nonRegisteredPartyMembers; + } +} diff --git a/contracts/lit-node/BackupRecovery/LibBackupRecoveryStorage.sol b/contracts/lit-node/BackupRecovery/LibBackupRecoveryStorage.sol new file mode 100644 index 0000000..20f2900 --- /dev/null +++ b/contracts/lit-node/BackupRecovery/LibBackupRecoveryStorage.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { IPubkeyRouter } from "../../lit-node/PubkeyRouter/LibPubkeyRouterStorage.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { EnumerableMap } from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + +library LibBackupRecoveryStorage { + using EnumerableSet for EnumerableSet.AddressSet; + bytes32 constant BACKUP_RECOVERY_POSITION = + keccak256("backuprecovery.storage"); + + /** + * @dev + * Simply maps a backup party member to the node that generated their backup share + */ + struct RecoveryPair { + address backupPartyAddress; + address nodeAddress; + bool isRegistered; + } + + /** + * @dev + * Holds the current backup party state + */ + struct BackupRecoveryState { + bytes sessionId; + bytes bls12381G1EncKey; + bytes secp256K1EcdsaPubKey; + uint256 partyThreshold; + address[] partyMembers; + } + + struct RecoveryKey { + bytes pubkey; + uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. + } + + /** + * @dev + * Holds the votes per Recovery pubKey + */ + struct VotesToRegisterRecoveryKey { + uint256 votes; + mapping(address => bool) voted; + } + + /** + * @dev + * Holds the next state of the backup party + */ + struct NextState { + address[] partyMembers; + mapping(address => address) peerToBackupMemberMapping; + uint nodesAssignedCount; + mapping(address => address) backupMemberPeerMapping; + mapping(address => bool) keysRecieved; + mapping(address => K256Proof) proofsRecieved; + // pubkey -> votes + mapping(bytes => VotesToRegisterRecoveryKey) votesToRegisterRecoveryKeys; + RecoveryKey[] registeredRecoveryKeys; + bytes sessionId; + bytes encryptedBlsKey; + uint256 partyThreshold; + bytes pubkey; + bytes curve; + } + + struct K256Proof { + bytes1 version; + uint256 timestamp; + bytes1 particpantId; + bytes schnorrProof; + bytes schnorrVerification; + bytes ecdsaProof; + bytes ecdsaVerificationKey; + } + + struct NextStateDownloadable { + address[] partyMembers; + RecoveryKey[] registeredRecoveryKeys; + } + + struct BackupRecoveryStorage { + bytes1 verificationVersion; + // current state of the backup recovery + mapping(uint256 => BackupRecoveryState) recoveryState; + // holds the next party state until promoted to active + mapping(uint256 => NextState) nextState; + // holds past states after a new backup party is registered + mapping(bytes => BackupRecoveryState) pastBackupStates; + // proof submission mapping + mapping(address => uint256[]) submittedProofs; + // instance of the deployed contract resolver + ContractResolver resolver; + // env context + ContractResolver.Env env; + // Status of the recovering nodes + mapping(uint256 => NodeRecoveryStatusMap[]) nodeStatusMap; + } + + function getStorage() + internal + pure + returns (BackupRecoveryStorage storage storageStruct) + { + bytes32 position = BACKUP_RECOVERY_POSITION; + assembly { + storageStruct.slot := position + } + } + + enum NodeRecoveryStatus { + Null, + StartedInRestoreState, + BackupsAreLoaded, + AllKeysAreRestored, + AbandonedRecoveryDueToNetworkState + } + + struct NodeRecoveryStatusMap { + address node_address; + NodeRecoveryStatus status; + } +} diff --git a/contracts/lit-node/HDKeyDeriver.sol b/contracts/lit-node/HDKeyDeriver.sol new file mode 100644 index 0000000..d568bbd --- /dev/null +++ b/contracts/lit-node/HDKeyDeriver.sol @@ -0,0 +1,96 @@ +//SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity ^0.8.17; +import { IPubkeyRouter } from "./PubkeyRouter/LibPubkeyRouterStorage.sol"; + +abstract contract IKeyDeriver { + function computeHDPubKey( + bytes32 derivedKeyId, + IPubkeyRouter.RootKey[] memory rootHDKeys, + uint256 keyType + ) public view virtual returns (bool, bytes memory); +} + +contract KeyDeriver is IKeyDeriver { + // address for HD public KDF + address public constant HD_KDF = 0x00000000000000000000000000000000000000F5; + // hd kdf ctx + string constant HD_KDF_CTX = "LIT_HD_KEY_ID_K256_XMD:SHA-256_SSWU_RO_NUL_"; + + constructor() {} + + function computeHDPubKey( + bytes32 derivedKeyId, + IPubkeyRouter.RootKey[] memory rootHDKeys, + uint256 keyType + ) public view override returns (bool, bytes memory) { + bytes memory args = _buildArgs(derivedKeyId, rootHDKeys, keyType); + (bool success, bytes memory data) = HD_KDF.staticcall(args); + return (success, data); + } + + function _buildArgs( + bytes32 derivedKeyId, + IPubkeyRouter.RootKey[] memory rootHDKeys, + uint256 keyType + ) internal pure returns (bytes memory) { + // empty array for concating pubkeys + bytes memory rootPubkeys = new bytes(0); + uint32 numRootPubkeys = 0; + for (uint256 i = 0; i < rootHDKeys.length; i++) { + if (rootHDKeys[i].keyType == keyType) { + rootPubkeys = abi.encodePacked( + rootPubkeys, + rootHDKeys[i].pubkey + ); + numRootPubkeys++; + } + } + + // so in Lit land, we use 2 for ECDSA secp256k1 keyType. + // but the precompile expects 1 for secp256k1 + // someday, we may add keyType 3 for ECDSA p256, which the precompile expects as "0" + if (keyType == 2) { + keyType = 1; + // assuming p256 curve type will be value '3' + } else if (keyType == 3) { + keyType = 0; + } + + bytes memory CTX = bytes(HD_KDF_CTX); + bytes1 kt = bytes1(uint8(keyType)); + bytes4 id_len = bytes4(uint32(derivedKeyId.length)); + bytes4 ctx_len = bytes4(uint32(CTX.length)); + bytes4 pubkey_len = bytes4(numRootPubkeys); + + bytes memory args_bytes = abi.encodePacked( + kt, // 1st arg is a byte for the curve type, 0 is Nist Prime256, 1 is secp256k1 + id_len, // 2nd arg is a 4 byte big-endian integer for the number of bytes in id + derivedKeyId, // 3rd arg is the byte sequence for id + ctx_len, // 4th arg is a 4 byte big-endian integer for the number of bytes in cxt + CTX, // 5th arg is the byte sequence for cxt + pubkey_len, // 6th arg is a 4 byte big-endian integer for the number of root keys + rootPubkeys // 7th arg is a variable number of root keys each 33 bytes (compressed) or 65 bytes (uncompressed) in length + ); + + return args_bytes; + } +} + +contract DevKeyDeriver is IKeyDeriver { + constructor() {} + + function computeHDPubKey( + bytes32 derivedKeyId, + IPubkeyRouter.RootKey[] memory rootHDKeys, + uint256 keyType + ) public view override returns (bool, bytes memory) { + // TODO: This is a temporary fix for lack of precompiles in test enviorments + // this is a non ideal as it does not truly exercise our KDF + // reference for followup refactor: https://linear.app/litprotocol/issue/LIT-1192/add-precompiles-to-anvil-through-forked-version-of-revm + + bytes + memory pubkey = hex"047c3647345020536e8aaccac7f73c5248bf3609677997fb615c290cc58e8ac1dcad1fa1d4f6eedf516f023dee11fbc06310434c5a7ee40f5f8c49e255b1d1bfb6"; + return (true, pubkey); + } +} diff --git a/contracts/LITToken.sol b/contracts/lit-node/LITToken.sol similarity index 97% rename from contracts/LITToken.sol rename to contracts/lit-node/LITToken.sol index f26911a..02aebbc 100644 --- a/contracts/LITToken.sol +++ b/contracts/lit-node/LITToken.sol @@ -21,7 +21,7 @@ import { ERC20Votes } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20 /// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol contract LITToken is AccessControl, - ERC20("Lit Protocol", "LIT"), + ERC20("Lit Test Token", "testLIT"), ERC20Burnable, ERC20Capped, ERC20Pausable, @@ -111,7 +111,7 @@ contract LITToken is address to, uint256 amount ) internal virtual override(ERC20, ERC20Votes) { - super._beforeTokenTransfer(from, to, amount); + super._afterTokenTransfer(from, to, amount); } function _burn( diff --git a/contracts/Multisender.sol b/contracts/lit-node/Multisender.sol similarity index 91% rename from contracts/Multisender.sol rename to contracts/lit-node/Multisender.sol index a85103d..09bac2e 100644 --- a/contracts/Multisender.sol +++ b/contracts/lit-node/Multisender.sol @@ -14,9 +14,10 @@ contract Multisender is Ownable { } } - function sendTokens(address[] calldata _recipients, address tokenContract) - public - { + function sendTokens( + address[] calldata _recipients, + address tokenContract + ) public { ERC20 tkn = ERC20(tokenContract); uint256 bal = tkn.balanceOf(address(this)); uint256 val = bal / _recipients.length; diff --git a/contracts/lit-node/PKPHelper.sol b/contracts/lit-node/PKPHelper.sol new file mode 100644 index 0000000..9080469 --- /dev/null +++ b/contracts/lit-node/PKPHelper.sol @@ -0,0 +1,525 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { PKPPermissions } from "./PKPPermissions.sol"; +import { PKPNFT } from "./PKPNFT.sol"; +import { PKPNFTMetadata } from "./PKPNFTMetadata.sol"; +import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; +import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { PKPNFTFacet } from "./PKPNFT/PKPNFTFacet.sol"; +import "@openzeppelin/contracts/access/AccessControl.sol"; +import "hardhat/console.sol"; + +import { LibPKPPermissionsStorage } from "./PKPPermissions/LibPKPPermissionsStorage.sol"; +import { PKPPermissionsFacet } from "./PKPPermissions/PKPPermissionsFacet.sol"; +import { LibPKPNFTStorage } from "./PKPNFT/LibPKPNFTStorage.sol"; + +// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn + +/// @title Programmable Keypair NFT +/// +/// @dev This is the contract for the PKP NFTs +/// +/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. +/// The owner can also grant signing permissions to other eth addresses +/// or lit actions +contract PKPHelper is Ownable, IERC721Receiver, AccessControl { + /* ========== CUSTOM STRUCTS ========== */ + struct AuthMethodData { + uint256 keyType; + bytes[] permittedIpfsCIDs; + uint256[][] permittedIpfsCIDScopes; + address[] permittedAddresses; + uint256[][] permittedAddressScopes; + uint256[] permittedAuthMethodTypes; + bytes[] permittedAuthMethodIds; + bytes[] permittedAuthMethodPubkeys; + uint256[][] permittedAuthMethodScopes; + bool addPkpEthAddressAsPermittedAddress; + bool sendPkpToItself; + } + + /* ========== STATE VARIABLES ========== */ + + ContractResolver public contractResolver; + ContractResolver.Env public env; + + /* ========== CONSTRUCTOR ========== */ + constructor(address _resolver, ContractResolver.Env _env) { + contractResolver = ContractResolver(_resolver); + env = _env; + } + + /* ========== VIEWS ========== */ + function getPkpNftAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_NFT_CONTRACT(), + env + ); + } + + function getPkpPermissionsAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_PERMISSIONS_CONTRACT(), + env + ); + } + + function getPKPNftMetdataAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_NFT_METADATA_CONTRACT(), + env + ); + } + + function getDomainWalletRegistry() public view returns (address) { + return + contractResolver.getContract( + contractResolver.DOMAIN_WALLET_REGISTRY(), + env + ); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + function mintNextAndAddAuthMethods( + uint256 keyType, + uint256[] memory permittedAuthMethodTypes, + bytes[] memory permittedAuthMethodIds, + bytes[] memory permittedAuthMethodPubkeys, + uint256[][] memory permittedAuthMethodScopes, + bool addPkpEthAddressAsPermittedAddress, + bool sendPkpToItself + ) public payable returns (uint256) { + return + mintNextAndAddAuthMethodsWithTypes( + keyType, + new bytes[](0), // permitted ipfs CIDs + new uint256[][](0), // permitted ipfs CIDs scopes + new address[](0), // permitted addresses + new uint256[][](0), // permitted addresses scopes + permittedAuthMethodTypes, + permittedAuthMethodIds, + permittedAuthMethodPubkeys, + permittedAuthMethodScopes, + addPkpEthAddressAsPermittedAddress, + sendPkpToItself + ); + } + + /* + Broken out into its own top level minting function as adding more parameters to + mintNextAndAddAuthMethodsWithTypes throws compile time errors relating to the amount of variables overflowing + the op code call stack. + See here for more info: https://ethereum.stackexchange.com/questions/6061/error-while-compiling-stack-too-deep + */ + function mintNextAndAddDomainWalletMetadata( + uint256 keyType, + uint256[] memory permittedAuthMethodTypes, + bytes[] memory permittedAuthMethodIds, + bytes[] memory permittedAuthMethodPubkeys, + uint256[][] memory permittedAuthMethodScopes, + string[] memory nftMetadata, + bool addPkpEthAddressAsPermittedAddress, + bool sendPkpToItself + ) public payable returns (uint256) { + require( + msg.sender == + contractResolver.getContract( + contractResolver.DOMAIN_WALLET_REGISTRY(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets, who are you?" + ); + + // mint the nft and forward the funds + uint256 tokenId = PKPNFTFacet(getPkpNftAddress()).mintNext{ + value: msg.value + }(keyType); + require( + permittedAuthMethodTypes.length == permittedAuthMethodIds.length, + "PKPHelper: auth method type and id array lengths must match" + ); + require( + permittedAuthMethodTypes.length == + permittedAuthMethodPubkeys.length, + "PKPHelper: auth method type and pubkey array lengths must match" + ); + require( + permittedAuthMethodTypes.length == permittedAuthMethodScopes.length, + "PKPHelper: auth method type and scopes array lengths must match" + ); + + // permit the auth method + if (permittedAuthMethodTypes.length != 0) { + for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAuthMethod( + tokenId, + LibPKPPermissionsStorage.AuthMethod( + permittedAuthMethodTypes[i], + permittedAuthMethodIds[i], + permittedAuthMethodPubkeys[i] + ), + permittedAuthMethodScopes[i] + ); + } + } + + address pkpEthAddress = PKPPermissionsFacet(getPkpPermissionsAddress()) + .getEthAddress(tokenId); + + // add the pkp eth address as a permitted address + if (addPkpEthAddressAsPermittedAddress) { + PKPPermissionsFacet(getPkpPermissionsAddress()).addPermittedAddress( + tokenId, + pkpEthAddress, + new uint256[](0) + ); + } + + if (sendPkpToItself) { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + pkpEthAddress, + tokenId + ); + } else { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + msg.sender, + tokenId + ); + } + + if (nftMetadata.length > 0) { + // first element is the full domain of the pkp (domain wallet url) + PKPNFTMetadata(getPKPNftMetdataAddress()).setUrlForPKP( + tokenId, + nftMetadata[0] + ); + // second element is the image url + PKPNFTMetadata(getPKPNftMetdataAddress()).setProfileForPKP( + tokenId, + nftMetadata[1] + ); + } + + return tokenId; + } + + function mintNextAndAddAuthMethodsWithTypes( + uint256 keyType, + bytes[] memory permittedIpfsCIDs, + uint256[][] memory permittedIpfsCIDScopes, + address[] memory permittedAddresses, + uint256[][] memory permittedAddressScopes, + uint256[] memory permittedAuthMethodTypes, + bytes[] memory permittedAuthMethodIds, + bytes[] memory permittedAuthMethodPubkeys, + uint256[][] memory permittedAuthMethodScopes, + bool addPkpEthAddressAsPermittedAddress, + bool sendPkpToItself + ) public payable returns (uint256) { + // mint the nft and forward the funds + uint256 tokenId = PKPNFTFacet(getPkpNftAddress()).mintNext{ + value: msg.value + }(keyType); + + // sanity checking array lengths + require( + permittedIpfsCIDs.length == permittedIpfsCIDScopes.length, + "PKPHelper: ipfs cid and scope array lengths must match" + ); + require( + permittedAddresses.length == permittedAddressScopes.length, + "PKPHelper: address and scope array lengths must match" + ); + require( + permittedAuthMethodTypes.length == permittedAuthMethodIds.length, + "PKPHelper: auth method type and id array lengths must match" + ); + require( + permittedAuthMethodTypes.length == + permittedAuthMethodPubkeys.length, + "PKPHelper: auth method type and pubkey array lengths must match" + ); + require( + permittedAuthMethodTypes.length == permittedAuthMethodScopes.length, + "PKPHelper: auth method type and scopes array lengths must match" + ); + + // permit the action + if (permittedIpfsCIDs.length != 0) { + for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAction( + tokenId, + permittedIpfsCIDs[i], + permittedIpfsCIDScopes[i] + ); + } + } + + // permit the address + if (permittedAddresses.length != 0) { + for (uint256 i = 0; i < permittedAddresses.length; i++) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAddress( + tokenId, + permittedAddresses[i], + permittedAddressScopes[i] + ); + } + } + + // permit the auth method + if (permittedAuthMethodTypes.length != 0) { + for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAuthMethod( + tokenId, + LibPKPPermissionsStorage.AuthMethod( + permittedAuthMethodTypes[i], + permittedAuthMethodIds[i], + permittedAuthMethodPubkeys[i] + ), + permittedAuthMethodScopes[i] + ); + } + } + + address pkpEthAddress = PKPPermissionsFacet(getPkpPermissionsAddress()) + .getEthAddress(tokenId); + + // add the pkp eth address as a permitted address + if (addPkpEthAddressAsPermittedAddress) { + PKPPermissionsFacet(getPkpPermissionsAddress()).addPermittedAddress( + tokenId, + pkpEthAddress, + new uint256[](0) + ); + } + + if (sendPkpToItself) { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + pkpEthAddress, + tokenId + ); + } else { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + msg.sender, + tokenId + ); + } + + return tokenId; + } + + // helper for the domain wallet registry registering pre existing pkps + function setPkpMetadata( + uint256 tokenId, + string[] memory nftMetadata + ) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.DOMAIN_WALLET_REGISTRY(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets, who are you?" + ); + PKPNFTMetadata pkpNftMetadata = PKPNFTMetadata( + getPKPNftMetdataAddress() + ); + + if (nftMetadata.length > 0) { + // first element is a url name for the pkp (domain wallet url) + pkpNftMetadata.setUrlForPKP(tokenId, nftMetadata[0]); + // first element is a url name for the pkp (domain wallet profile image url) + pkpNftMetadata.setProfileForPKP(tokenId, nftMetadata[1]); + } + } + + function removePkpMetadata(uint256 tokenId) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.DOMAIN_WALLET_REGISTRY(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets, who are you?" + ); + PKPNFTMetadata pkpNftMetadata = PKPNFTMetadata( + getPKPNftMetdataAddress() + ); + pkpNftMetadata.removeProfileForPkp(tokenId); + pkpNftMetadata.removeUrlForPKP(tokenId); + } + + function claimAndMintNextAndAddAuthMethods( + LibPKPNFTStorage.ClaimMaterial memory claimMaterial, + AuthMethodData memory authMethodData + ) public payable returns (uint256) { + return + claimAndMintNextAndAddAuthMethodsWithTypes( + claimMaterial, + authMethodData + ); + } + + function claimAndMintNextAndAddAuthMethodsWithTypes( + LibPKPNFTStorage.ClaimMaterial memory claimMaterial, + AuthMethodData memory authMethodData + ) public payable returns (uint256) { + require( + claimMaterial.keyType == authMethodData.keyType, + "PKPHelper: Claim key type must match Auth Method data key type" + ); + // mint the nft and forward the funds + uint256 tokenId = PKPNFTFacet(getPkpNftAddress()).claimAndMint{ + value: msg.value + }( + claimMaterial.keyType, + claimMaterial.derivedKeyId, + claimMaterial.signatures + ); + + require( + authMethodData.permittedIpfsCIDs.length == + authMethodData.permittedIpfsCIDScopes.length, + "PKPHelper: ipfs cid and scope array lengths must match" + ); + // sanity checking array lengths + require( + authMethodData.permittedAddresses.length == + authMethodData.permittedAddressScopes.length, + "PKPHelper: address and scope array lengths must match" + ); + require( + authMethodData.permittedAuthMethodTypes.length == + authMethodData.permittedAuthMethodIds.length, + "PKPHelper: auth method type and id array lengths must match" + ); + require( + authMethodData.permittedAuthMethodTypes.length == + authMethodData.permittedAuthMethodPubkeys.length, + "PKPHelper: auth method type and pubkey array lengths must match" + ); + require( + authMethodData.permittedAuthMethodTypes.length == + authMethodData.permittedAuthMethodScopes.length, + "PKPHelper: auth method type and scopes array lengths must match" + ); + + if (authMethodData.permittedIpfsCIDs.length != 0) { + for ( + uint256 i = 0; + i < authMethodData.permittedIpfsCIDs.length; + i++ + ) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAction( + tokenId, + authMethodData.permittedIpfsCIDs[i], + authMethodData.permittedIpfsCIDScopes[i] + ); + } + } + + // permit the address + if (authMethodData.permittedAddresses.length != 0) { + for ( + uint256 i = 0; + i < authMethodData.permittedAddresses.length; + i++ + ) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAddress( + tokenId, + authMethodData.permittedAddresses[i], + authMethodData.permittedAddressScopes[i] + ); + } + } + + // permit the auth method + if (authMethodData.permittedAuthMethodTypes.length != 0) { + for ( + uint256 i = 0; + i < authMethodData.permittedAuthMethodTypes.length; + i++ + ) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAuthMethod( + tokenId, + LibPKPPermissionsStorage.AuthMethod( + authMethodData.permittedAuthMethodTypes[i], + authMethodData.permittedAuthMethodIds[i], + authMethodData.permittedAuthMethodPubkeys[i] + ), + authMethodData.permittedAuthMethodScopes[i] + ); + } + } + + address pkpEthAddress = PKPPermissionsFacet(getPkpPermissionsAddress()) + .getEthAddress(tokenId); + + // add the pkp eth address as a permitted address + if (authMethodData.addPkpEthAddressAsPermittedAddress) { + PKPPermissionsFacet(getPkpPermissionsAddress()).addPermittedAddress( + tokenId, + pkpEthAddress, + new uint256[](0) + ); + } + + if (authMethodData.sendPkpToItself) { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + pkpEthAddress, + tokenId + ); + } else { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + msg.sender, + tokenId + ); + } + + return tokenId; + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + contractResolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); + } + + function onERC721Received( + address /* operator */, + address /* from */, + uint256 /* tokenId */, + bytes calldata /* data */ + ) external view override returns (bytes4) { + // only accept transfers from the pkpNft contract + + require( + msg.sender == getPkpNftAddress(), + "PKPHelper: only accepts transfers from the PKPNFT contract" + ); + return this.onERC721Received.selector; + } + + /* ========== EVENTS ========== */ + + event ContractResolverAddressSet(address newResolverAddress); +} diff --git a/contracts/lit-node/PKPHelperV2.sol b/contracts/lit-node/PKPHelperV2.sol new file mode 100644 index 0000000..1e82eff --- /dev/null +++ b/contracts/lit-node/PKPHelperV2.sol @@ -0,0 +1,181 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { PKPNFTFacet } from "./PKPNFT/PKPNFTFacet.sol"; +import "hardhat/console.sol"; + +import { LibPKPPermissionsStorage } from "./PKPPermissions/LibPKPPermissionsStorage.sol"; +import { PKPPermissionsFacet } from "./PKPPermissions/PKPPermissionsFacet.sol"; +import { LibPKPNFTStorage } from "./PKPNFT/LibPKPNFTStorage.sol"; + +/// @title Version 2 of the stateless PKP Helper Contract +/// +/// @dev Permits a bunch of atomic operations on the PKP NFTs +contract PKPHelperV2 is Ownable, IERC721Receiver { + /* ========== CUSTOM STRUCTS ========== */ + struct NewPKPParams { + uint256 keyType; + uint256[] permittedAuthMethodTypes; + bytes[] permittedAuthMethodIds; + bytes[] permittedAuthMethodPubkeys; + uint256[][] permittedAuthMethodScopes; + bool addPkpEthAddressAsPermittedAddress; + uint256[] pkpEthAddressScopes; + bool sendPkpToItself; + bool burnPkp; + } + + /* ========== STATE VARIABLES ========== */ + + ContractResolver public contractResolver; + ContractResolver.Env public env; + + /* ========== CONSTRUCTOR ========== */ + constructor(address _resolver, ContractResolver.Env _env) { + contractResolver = ContractResolver(_resolver); + env = _env; + } + + /* ========== VIEWS ========== */ + function getPkpNftAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_NFT_CONTRACT(), + env + ); + } + + function getPkpPermissionsAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_PERMISSIONS_CONTRACT(), + env + ); + } + + function getPKPNftMetdataAddress() public view returns (address) { + return + contractResolver.getContract( + contractResolver.PKP_NFT_METADATA_CONTRACT(), + env + ); + } + + function getDomainWalletRegistry() public view returns (address) { + return + contractResolver.getContract( + contractResolver.DOMAIN_WALLET_REGISTRY(), + env + ); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + function mintNextAndAddAuthMethods( + NewPKPParams memory params + ) public payable returns (uint256) { + return mintNextAndAddAuthMethodsWithTypes(params); + } + + function mintNextAndAddAuthMethodsWithTypes( + NewPKPParams memory params + ) public payable returns (uint256) { + // mint the nft and forward the funds + uint256 tokenId = PKPNFTFacet(getPkpNftAddress()).mintNext{ + value: msg.value + }(params.keyType); + + require( + params.permittedAuthMethodTypes.length == + params.permittedAuthMethodIds.length, + "PKPHelper: auth method type and id array lengths must match" + ); + require( + params.permittedAuthMethodTypes.length == + params.permittedAuthMethodPubkeys.length, + "PKPHelper: auth method type and pubkey array lengths must match" + ); + require( + params.permittedAuthMethodTypes.length == + params.permittedAuthMethodScopes.length, + "PKPHelper: auth method type and scopes array lengths must match" + ); + + // permit the auth methoda + if (params.permittedAuthMethodTypes.length != 0) { + for ( + uint256 i = 0; + i < params.permittedAuthMethodTypes.length; + i++ + ) { + PKPPermissionsFacet(getPkpPermissionsAddress()) + .addPermittedAuthMethod( + tokenId, + LibPKPPermissionsStorage.AuthMethod( + params.permittedAuthMethodTypes[i], + params.permittedAuthMethodIds[i], + params.permittedAuthMethodPubkeys[i] + ), + params.permittedAuthMethodScopes[i] + ); + } + } + + address pkpEthAddress = PKPPermissionsFacet(getPkpPermissionsAddress()) + .getEthAddress(tokenId); + + // add the pkp eth address as a permitted address + if (params.addPkpEthAddressAsPermittedAddress) { + PKPPermissionsFacet(getPkpPermissionsAddress()).addPermittedAddress( + tokenId, + pkpEthAddress, + params.pkpEthAddressScopes + ); + } + + if (params.sendPkpToItself) { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + pkpEthAddress, + tokenId + ); + } else if (params.burnPkp) { + PKPNFTFacet(getPkpNftAddress()).burn(tokenId); + } else { + PKPNFTFacet(getPkpNftAddress()).safeTransferFrom( + address(this), + msg.sender, + tokenId + ); + } + + return tokenId; + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + contractResolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); + } + + function onERC721Received( + address /* operator */, + address /* from */, + uint256 /* tokenId */, + bytes calldata /* data */ + ) external view override returns (bytes4) { + // only accept transfers from the pkpNft contract + + require( + msg.sender == getPkpNftAddress(), + "PKPHelper: only accepts transfers from the PKPNFT contract" + ); + return this.onERC721Received.selector; + } + + /* ========== EVENTS ========== */ + + event ContractResolverAddressSet(address newResolverAddress); +} diff --git a/contracts/lit-node/PKPNFT.sol b/contracts/lit-node/PKPNFT.sol new file mode 100644 index 0000000..9ef1b03 --- /dev/null +++ b/contracts/lit-node/PKPNFT.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibPKPNFTStorage } from "./PKPNFT/LibPKPNFTStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct StakingArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract PKPNFT { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + StakingArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibPKPNFTStorage.getStorage().contractResolver = ContractResolver( + _args.contractResolver + ); + LibPKPNFTStorage.getStorage().env = _args.env; + + LibPKPNFTStorage.getStorage().mintCost = 1; // 1 wei + LibPKPNFTStorage.getStorage().freeMintSigner = _args.owner; + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/PKPNFT/LibPKPNFTStorage.sol b/contracts/lit-node/PKPNFT/LibPKPNFTStorage.sol new file mode 100644 index 0000000..8615b57 --- /dev/null +++ b/contracts/lit-node/PKPNFT/LibPKPNFTStorage.sol @@ -0,0 +1,40 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { IPubkeyRouter } from "../PubkeyRouter/LibPubkeyRouterStorage.sol"; + +library LibPKPNFTStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + bytes32 constant PKP_NFT_POSITION = keccak256("pkpnft.storage"); + + struct ClaimMaterial { + uint256 keyType; + bytes32 derivedKeyId; + IPubkeyRouter.Signature[] signatures; + } + + struct PKPNFTStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + uint256 mintCost; + address freeMintSigner; + mapping(uint256 => bool) redeemedFreeMintIds; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (PKPNFTStorage storage storageStruct) + { + bytes32 position = PKP_NFT_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/PKPNFT/PKPNFTFacet.sol b/contracts/lit-node/PKPNFT/PKPNFTFacet.sol new file mode 100644 index 0000000..1639808 --- /dev/null +++ b/contracts/lit-node/PKPNFT/PKPNFTFacet.sol @@ -0,0 +1,314 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ERC721Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/ERC721Upgradeable.sol"; +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { ERC721BurnableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; +import { ERC721EnumerableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; +import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; +import { ERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/ERC165Upgradeable.sol"; +import { IERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/IERC165Upgradeable.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { LibPKPNFTStorage } from "./LibPKPNFTStorage.sol"; +import { IPubkeyRouter } from "../PubkeyRouter/LibPubkeyRouterStorage.sol"; +import { PubkeyRouterFacet } from "../PubkeyRouter/PubkeyRouterFacet.sol"; +import { PKPNFTMetadata } from "../PKPNFTMetadata.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { PKPPermissionsFacet } from "../PKPPermissions/PKPPermissionsFacet.sol"; + +import "hardhat/console.sol"; + +// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn + +/// @title Programmable Keypair NFT +/// +/// @dev This is the contract for the PKP NFTs +/// +/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. +/// The owner can also grant signing permissions to other eth addresses +/// or lit actions +contract PKPNFTFacet is + ERC721Upgradeable, + ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable +{ + using Strings for uint256; + + error CallerNotOwner(); + + function initialize() public initializer { + __ERC721_init("Programmable Keypair", "PKP"); + } + + /* ========== Modifiers ========== */ + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + + function s() + internal + pure + returns (LibPKPNFTStorage.PKPNFTStorage storage) + { + return LibPKPNFTStorage.getStorage(); + } + + /// get the staking address from the resolver + function getStakingAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.STAKING_CONTRACT(), + s().env + ); + } + + function getRouterAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PUB_KEY_ROUTER_CONTRACT(), + s().env + ); + } + + function getPkpNftMetadataAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PKP_NFT_METADATA_CONTRACT(), + s().env + ); + } + + function getPkpPermissionsAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PKP_PERMISSIONS_CONTRACT(), + s().env + ); + } + + function mintCost() public view returns (uint256) { + return s().mintCost; + } + + function freeMintSigner() public view returns (address) { + return s().freeMintSigner; + } + + function redeemedFreeMintIds(uint256 tokenId) public view returns (bool) { + return s().redeemedFreeMintIds[tokenId]; + } + + /// get the eth address for the keypair + function getEthAddress(uint256 tokenId) public view returns (address) { + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + return router.getEthAddress(tokenId); + } + + /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress + function getPubkey(uint256 tokenId) public view returns (bytes memory) { + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + return router.getPubkey(tokenId); + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface( + bytes4 interfaceId + ) + public + view + virtual + override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + returns (bool) + { + return + super.supportsInterface(interfaceId) || + LibDiamond.diamondStorage().supportedInterfaces[interfaceId]; + } + + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId, + uint256 batchSize + ) + internal + virtual + override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + { + ERC721EnumerableUpgradeable._beforeTokenTransfer( + from, + to, + tokenId, + batchSize + ); + } + + function tokenURI( + uint256 tokenId + ) public view override returns (string memory) { + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + bytes memory pubKey = router.getPubkey(tokenId); + address ethAddress = router.getEthAddress(tokenId); + + PKPNFTMetadata pkpNftMetadata = PKPNFTMetadata( + getPkpNftMetadataAddress() + ); + return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress); + } + + // Builds a prefixed hash to mimic the behavior of eth_sign. + function prefixed(bytes32 hash) public pure returns (bytes32) { + return + keccak256( + abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) + ); + } + + function exists(uint256 tokenId) public view returns (bool) { + return _exists(tokenId); + } + + function getNextDerivedKeyId() public view returns (bytes32) { + uint256 tokenCount = totalSupply() + 1; + // hash(tokenCount, previousBlockHash) + bytes32 derivedKeyId = keccak256( + abi.encodePacked(tokenCount, blockhash(block.number - 1)) + ); + + return derivedKeyId; + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + function mintNext(uint256 keyType) public payable returns (uint256) { + require(msg.value == s().mintCost, "You must pay exactly mint cost"); + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + bytes32 derivedKeyId = getNextDerivedKeyId(); + bytes memory pubkey = router.getDerivedPubkey( + getStakingAddress(), + derivedKeyId + ); + uint256 tokenId = uint256(keccak256(pubkey)); + routeDerivedKey(keyType, derivedKeyId); + _mintWithoutValueCheck(tokenId, msg.sender); + return tokenId; + } + + function claimAndMint( + uint256 keyType, + bytes32 derivedKeyId, + IPubkeyRouter.Signature[] memory signatures + ) public payable returns (uint256) { + require(msg.value == s().mintCost, "You must pay exactly mint cost"); + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + router.checkNodeSignatures( + signatures, + abi.encodePacked(derivedKeyId), + getStakingAddress() + ); + bytes memory pubkey = router.getDerivedPubkey( + getStakingAddress(), + derivedKeyId + ); + uint256 tokenId = uint256(keccak256(pubkey)); + + routeDerivedKey(keyType, derivedKeyId); + _mintWithoutValueCheck(tokenId, msg.sender); + + return tokenId; + } + + function mintGrantAndBurnNext( + uint256 keyType, + bytes memory ipfsCID + ) public payable returns (uint256) { + require(msg.value == s().mintCost, "You must pay exactly mint cost"); + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + bytes32 derivedKeyId = getNextDerivedKeyId(); + bytes memory pubkey = router.getDerivedPubkey( + getStakingAddress(), + derivedKeyId + ); + uint256 tokenId = uint256(keccak256(pubkey)); + routeDerivedKey(keyType, derivedKeyId); + _mintWithoutValueCheck(tokenId, address(this)); + uint256[] memory scopes = new uint256[](1); + scopes[0] = 1; + PKPPermissionsFacet(getPkpPermissionsAddress()).addPermittedAction( + tokenId, + ipfsCID, + scopes + ); + _burn(tokenId); + return tokenId; + } + + function routeDerivedKey(uint256 keyType, bytes32 derivedKeyId) internal { + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + bytes memory pubkey = router.getDerivedPubkey( + getStakingAddress(), + derivedKeyId + ); + uint256 tokenId = uint256(keccak256(pubkey)); + + PubkeyRouterFacet(getRouterAddress()).setRoutingData( + tokenId, + pubkey, + address(getStakingAddress()), + keyType, + derivedKeyId + ); + } + + function _mintWithoutValueCheck(uint256 tokenId, address to) internal { + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + require(router.isRouted(tokenId), "This PKP has not been routed yet"); + + if (to == address(this)) { + // permit unsafe transfer only to this contract, because it's going to be burned + _mint(to, tokenId); + } else { + _safeMint(to, tokenId); + } + emit PKPMinted(tokenId, getPubkey(tokenId)); + } + + function setMintCost(uint256 newMintCost) public onlyOwner { + s().mintCost = newMintCost; + emit MintCostSet(newMintCost); + } + + function setFreeMintSigner(address newFreeMintSigner) public onlyOwner { + s().freeMintSigner = newFreeMintSigner; + emit FreeMintSignerSet(newFreeMintSigner); + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + s().contractResolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); + } + + function withdraw() public onlyOwner { + uint256 withdrawAmount = address(this).balance; + (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); + require(sent); + emit Withdrew(withdrawAmount); + } + + /* ========== EVENTS ========== */ + + event MintCostSet(uint256 newMintCost); + event FreeMintSignerSet(address indexed newFreeMintSigner); + event Withdrew(uint256 amount); + event PKPMinted(uint256 indexed tokenId, bytes pubkey); + event ContractResolverAddressSet(address newResolverAddress); +} diff --git a/contracts/lit-node/PKPNFTMetadata.sol b/contracts/lit-node/PKPNFTMetadata.sol new file mode 100644 index 0000000..25fdd4c --- /dev/null +++ b/contracts/lit-node/PKPNFTMetadata.sol @@ -0,0 +1,168 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +import "hardhat/console.sol"; +import "@openzeppelin/contracts/access/AccessControl.sol"; +import { ContractResolver } from "../lit-core/ContractResolver.sol"; + +/// @title Programmable Keypair NFT Metadata +/// +/// @dev This is the contract for the PKP NFTs +/// +/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message. +/// The owner can also grant signing permissions to other eth addresses +/// or lit actions +contract PKPNFTMetadata { + using Strings for uint256; + + ContractResolver public contractResolver; + ContractResolver.Env public env; + + /* ========== STATE VARIABLES ========== */ + mapping(uint256 => string) pkpUrls; + mapping(uint256 => string) pkpProfileImg; + + /* ========== CONSTRUCTOR ========== */ + constructor(address _resolver, ContractResolver.Env _env) { + contractResolver = ContractResolver(_resolver); + env = _env; + } + + /* ========== VIEWS ========== */ + + function bytesToHex( + bytes memory buffer + ) public pure returns (string memory) { + // Fixed buffer size for hexadecimal convertion + bytes memory converted = new bytes(buffer.length * 2); + + bytes memory _base = "0123456789abcdef"; + + for (uint256 i = 0; i < buffer.length; i++) { + converted[i * 2] = _base[uint8(buffer[i]) / _base.length]; + converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length]; + } + + return string(abi.encodePacked("0x", converted)); + } + + function setUrlForPKP(uint256 tokenId, string memory url) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.PKP_HELPER_CONTRACT(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets" + ); + + pkpUrls[tokenId] = url; + } + + function setProfileForPKP(uint256 tokenId, string memory imgUrl) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.PKP_HELPER_CONTRACT(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets" + ); + + pkpProfileImg[tokenId] = imgUrl; + } + + function removeUrlForPKP(uint256 tokenId) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.PKP_HELPER_CONTRACT(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets" + ); + + pkpUrls[tokenId] = ""; + } + + function removeProfileForPkp(uint256 tokenId) public { + require( + msg.sender == + contractResolver.getContract( + contractResolver.PKP_HELPER_CONTRACT(), + env + ), + "PKPHelper: only the Domain Wallet registry is allowed to mint domain wallets" + ); + + pkpProfileImg[tokenId] = ""; + } + + function tokenURI( + uint256 tokenId, + bytes memory pubKey, + address ethAddress + ) public view returns (string memory) { + string memory json = resolveMetaData(tokenId, pubKey, ethAddress); + return string(abi.encodePacked("data:application/json;base64,", json)); + } + + function resolveMetaData( + uint256 tokenId, + bytes memory pubKey, + address ethAddress + ) private view returns (string memory) { + string + memory svgData = ""; + + string memory pubkeyStr = bytesToHex(pubKey); + // console.log("pubkeyStr"); + // console.log(pubkeyStr); + + string memory ethAddressStr = Strings.toHexString(ethAddress); + // console.log("ethAddressStr"); + // console.log(ethAddressStr); + + string memory tokenIdStr = Strings.toString(tokenId); + + string memory name = pkpUrls[tokenId]; + + string memory profileImage = pkpProfileImg[tokenId]; + + /// name is not registed + if (bytes(name).length == 0 && bytes(profileImage).length != 0) { + name = string.concat("Lit PKP #", tokenIdStr); + /// profile image is not defined + } else if (bytes(name).length != 0 && bytes(profileImage).length == 0) { + profileImage = svgData; + /// neither name or profile url are defined + } else if (bytes(name).length == 0 && bytes(profileImage).length == 0) { + name = string.concat("Lit PKP #", tokenIdStr); + profileImage = svgData; + } + + return + Base64.encode( + bytes( + string( + abi.encodePacked( + '{"name":"', + name, + '", "description": "This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP","image_data": "', + bytes(profileImage), + '","attributes": [{"trait_type": "Public Key", "value": "', + pubkeyStr, + '"}, {"trait_type": "ETH Wallet Address", "value": "', + ethAddressStr, + '"}, {"trait_type": "Token ID", "value": "', + tokenIdStr, + '"}]}' + ) + ) + ) + ); + } +} diff --git a/contracts/lit-node/PKPPermissions.sol b/contracts/lit-node/PKPPermissions.sol new file mode 100644 index 0000000..e994670 --- /dev/null +++ b/contracts/lit-node/PKPPermissions.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibPKPPermissionsStorage } from "./PKPPermissions/LibPKPPermissionsStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct PKPPermissionsArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract PKPPermissions { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + PKPPermissionsArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibPKPPermissionsStorage + .getStorage() + .contractResolver = ContractResolver(_args.contractResolver); + LibPKPPermissionsStorage.getStorage().env = _args.env; + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/PKPPermissions/LibPKPPermissionsStorage.sol b/contracts/lit-node/PKPPermissions/LibPKPPermissionsStorage.sol new file mode 100644 index 0000000..0d229e8 --- /dev/null +++ b/contracts/lit-node/PKPPermissions/LibPKPPermissionsStorage.sol @@ -0,0 +1,53 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; + +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +library LibPKPPermissionsStorage { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.Bytes32Set; + using EnumerableSet for EnumerableSet.UintSet; + using BytesLib for bytes; + using BitMaps for BitMaps.BitMap; + + bytes32 constant PKP_PERMISSIONS_POSITION = + keccak256("pkppermissions.storage"); + + struct AuthMethod { + uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT, 7 = OTP, 8 = Apple JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying. + bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID. + bytes userPubkey; // the user's pubkey. This is used for WebAuthn. + } + + struct PKPPermissionsStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + // map the keccack256(uncompressed pubkey) -> set of auth methods + mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods; + // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id + mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes; + // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct + mapping(uint256 => AuthMethod) authMethods; + // map the AuthMethod hash to the pubkeys that it's allowed to sign for + // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id + mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds; + // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash) + mapping(uint256 => mapping(uint256 => bytes32)) _rootHashes; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (PKPPermissionsStorage storage storageStruct) + { + bytes32 position = PKP_PERMISSIONS_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/PKPPermissions.sol b/contracts/lit-node/PKPPermissions/PKPPermissionsFacet.sol similarity index 61% rename from contracts/PKPPermissions.sol rename to contracts/lit-node/PKPPermissions/PKPPermissionsFacet.sol index 5b13e99..f89ab98 100644 --- a/contracts/PKPPermissions.sol +++ b/contracts/lit-node/PKPPermissions/PKPPermissionsFacet.sol @@ -1,27 +1,27 @@ //SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.17; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; - -import { PKPNFT } from "./PKPNFT.sol"; import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; + +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { PubkeyRouterFacet } from "../PubkeyRouter/PubkeyRouterFacet.sol"; +import { PKPNFTFacet } from "../PKPNFT/PKPNFTFacet.sol"; + +import { LibPKPPermissionsStorage } from "./LibPKPPermissionsStorage.sol"; import "hardhat/console.sol"; -contract PKPPermissions is Ownable { +contract PKPPermissionsFacet { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.UintSet; using BytesLib for bytes; using BitMaps for BitMaps.BitMap; - /* ========== STATE VARIABLES ========== */ - - PKPNFT public pkpNFT; - enum AuthMethodType { NULLMETHOD, // 0 ADDRESS, // 1 @@ -29,54 +29,69 @@ contract PKPPermissions is Ownable { WEBAUTHN, // 3 DISCORD, // 4 GOOGLE, // 5 - GOOGLE_JWT // 6 - } - - struct AuthMethod { - uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying. - bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID. - bytes userPubkey; // the user's pubkey. This is used for WebAuthn. + GOOGLE_JWT, // 6 + OTP, // 7 + APPLE_JWT, // 8 + STYTCH_JWT, // 9 + STYTCH_JWT_EMAIL_FACTOR, // 10 + STYTCH_JWT_SMS_FACTOR, // 11 + STYTCH_JWT_WHATS_APP_FACTOR, // 12 + STYTCH_JWT_TOTP_FACTOR // 13 } - // map the keccack256(uncompressed pubkey) -> set of auth methods - mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods; + /* ========== Errors ========== */ + error CallerNotOwner(); - // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id - mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes; - - // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct - mapping(uint256 => AuthMethod) public authMethods; - - // map the AuthMethod hash to the pubkeys that it's allowed to sign for - // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id - mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds; - - // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash) - mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes; - - /* ========== CONSTRUCTOR ========== */ - constructor(address _pkpNft) { - pkpNFT = PKPNFT(_pkpNft); - } - - /* ========== Modifier ========== */ + /* ========== Modifiers ========== */ modifier onlyPKPOwner(uint256 tokenId) { // check that user is allowed to set this + PKPNFTFacet pkpNFT = PKPNFTFacet(getPkpNftAddress()); address nftOwner = pkpNFT.ownerOf(tokenId); require(msg.sender == nftOwner, "Not PKP NFT owner"); _; } + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + /* ========== VIEWS ========== */ + function s() + internal + pure + returns (LibPKPPermissionsStorage.PKPPermissionsStorage storage) + { + return LibPKPPermissionsStorage.getStorage(); + } + + function getPkpNftAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PKP_NFT_CONTRACT(), + s().env + ); + } + + function getRouterAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PUB_KEY_ROUTER_CONTRACT(), + s().env + ); + } + /// get the eth address for the keypair, as long as it's an ecdsa keypair function getEthAddress(uint256 tokenId) public view returns (address) { - return pkpNFT.getEthAddress(tokenId); + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + return router.getEthAddress(tokenId); } /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress function getPubkey(uint256 tokenId) public view returns (bytes memory) { - return pkpNFT.getPubkey(tokenId); + PubkeyRouterFacet router = PubkeyRouterFacet(getRouterAddress()); + return router.getPubkey(tokenId); } function getAuthMethodId( @@ -92,7 +107,9 @@ contract PKPPermissions is Ownable { bytes calldata id ) external view returns (bytes memory) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - AuthMethod memory am = authMethods[authMethodId]; + LibPKPPermissionsStorage.AuthMethod memory am = s().authMethods[ + authMethodId + ]; return am.userPubkey; } @@ -102,11 +119,11 @@ contract PKPPermissions is Ownable { ) external view returns (uint256[] memory) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length(); + uint256 pkpIdsLength = s().authMethodToPkpIds[authMethodId].length(); uint256[] memory allPkpIds = new uint256[](pkpIdsLength); for (uint256 i = 0; i < pkpIdsLength; i++) { - allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i); + allPkpIds[i] = s().authMethodToPkpIds[authMethodId].at(i); } return allPkpIds; @@ -114,16 +131,18 @@ contract PKPPermissions is Ownable { function getPermittedAuthMethods( uint256 tokenId - ) external view returns (AuthMethod[] memory) { - uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId] + ) external view returns (LibPKPPermissionsStorage.AuthMethod[] memory) { + uint256 permittedAuthMethodsLength = s() + .permittedAuthMethods[tokenId] .length(); - AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[]( - permittedAuthMethodsLength - ); + LibPKPPermissionsStorage.AuthMethod[] + memory allPermittedAuthMethods = new LibPKPPermissionsStorage.AuthMethod[]( + permittedAuthMethodsLength + ); for (uint256 i = 0; i < permittedAuthMethodsLength; i++) { - uint256 authMethodHash = permittedAuthMethods[tokenId].at(i); - allPermittedAuthMethods[i] = authMethods[authMethodHash]; + uint256 authMethodHash = s().permittedAuthMethods[tokenId].at(i); + allPermittedAuthMethods[i] = s().authMethods[authMethodHash]; } return allPermittedAuthMethods; @@ -136,10 +155,8 @@ contract PKPPermissions is Ownable { uint256 maxScopeId ) public view returns (bool[] memory) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - BitMaps.BitMap - storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][ - authMethodId - ]; + BitMaps.BitMap storage permittedScopesBitMap = s() + .permittedAuthMethodScopes[tokenId][authMethodId]; bool[] memory allScopes = new bool[](maxScopeId); for (uint256 i = 0; i < maxScopeId; i++) { @@ -152,14 +169,17 @@ contract PKPPermissions is Ownable { function getPermittedActions( uint256 tokenId ) public view returns (bytes[] memory) { - uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId] + uint256 permittedAuthMethodsLength = s() + .permittedAuthMethods[tokenId] .length(); // count the number of auth methods that are actions uint256 permittedActionsLength = 0; for (uint256 i = 0; i < permittedAuthMethodsLength; i++) { - uint256 authMethodHash = permittedAuthMethods[tokenId].at(i); - AuthMethod memory am = authMethods[authMethodHash]; + uint256 authMethodHash = s().permittedAuthMethods[tokenId].at(i); + LibPKPPermissionsStorage.AuthMethod memory am = s().authMethods[ + authMethodHash + ]; if (am.authMethodType == uint256(AuthMethodType.ACTION)) { permittedActionsLength++; } @@ -171,8 +191,10 @@ contract PKPPermissions is Ownable { uint256 permittedActionsIndex = 0; for (uint256 i = 0; i < permittedAuthMethodsLength; i++) { - uint256 authMethodHash = permittedAuthMethods[tokenId].at(i); - AuthMethod memory am = authMethods[authMethodHash]; + uint256 authMethodHash = s().permittedAuthMethods[tokenId].at(i); + LibPKPPermissionsStorage.AuthMethod memory am = s().authMethods[ + authMethodHash + ]; if (am.authMethodType == uint256(AuthMethodType.ACTION)) { allPermittedActions[permittedActionsIndex] = am.id; permittedActionsIndex++; @@ -185,19 +207,23 @@ contract PKPPermissions is Ownable { function getPermittedAddresses( uint256 tokenId ) public view returns (address[] memory) { - uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId] + uint256 permittedAuthMethodsLength = s() + .permittedAuthMethods[tokenId] .length(); // count the number of auth methods that are addresses uint256 permittedAddressLength = 0; for (uint256 i = 0; i < permittedAuthMethodsLength; i++) { - uint256 authMethodHash = permittedAuthMethods[tokenId].at(i); - AuthMethod memory am = authMethods[authMethodHash]; + uint256 authMethodHash = s().permittedAuthMethods[tokenId].at(i); + LibPKPPermissionsStorage.AuthMethod memory am = s().authMethods[ + authMethodHash + ]; if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) { permittedAddressLength++; } } + PKPNFTFacet pkpNFT = PKPNFTFacet(getPkpNftAddress()); bool tokenExists = pkpNFT.exists(tokenId); address[] memory allPermittedAddresses; uint256 permittedAddressIndex = 0; @@ -215,8 +241,10 @@ contract PKPPermissions is Ownable { } for (uint256 i = 0; i < permittedAuthMethodsLength; i++) { - uint256 authMethodHash = permittedAuthMethods[tokenId].at(i); - AuthMethod memory am = authMethods[authMethodHash]; + uint256 authMethodHash = s().permittedAuthMethods[tokenId].at(i); + LibPKPPermissionsStorage.AuthMethod memory am = s().authMethods[ + authMethodHash + ]; if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) { address parsed; bytes memory id = am.id; @@ -243,7 +271,9 @@ contract PKPPermissions is Ownable { bytes memory id ) public view returns (bool) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - bool permitted = permittedAuthMethods[tokenId].contains(authMethodId); + bool permitted = s().permittedAuthMethods[tokenId].contains( + authMethodId + ); if (!permitted) { return false; } @@ -257,7 +287,7 @@ contract PKPPermissions is Ownable { uint256 scopeId ) public view returns (bool) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - bool present = permittedAuthMethodScopes[tokenId][authMethodId].get( + bool present = s().permittedAuthMethodScopes[tokenId][authMethodId].get( scopeId ); return present; @@ -279,20 +309,72 @@ contract PKPPermissions is Ownable { uint256 tokenId, address user ) public view returns (bool) { + PKPNFTFacet pkpNFT = PKPNFTFacet(getPkpNftAddress()); + bool userIsOwner = false; + if (pkpNFT.exists(tokenId)) { + address nftOwner = pkpNFT.ownerOf(tokenId); + userIsOwner = nftOwner == user; + } return isPermittedAuthMethod( tokenId, uint256(AuthMethodType.ADDRESS), abi.encodePacked(user) - ) || pkpNFT.ownerOf(tokenId) == user; + ) || userIsOwner; } /* ========== MUTATIVE FUNCTIONS ========== */ + function batchAddRemoveAuthMethods( + uint256 tokenId, + uint256[] memory permittedAuthMethodTypesToAdd, + bytes[] memory permittedAuthMethodIdsToAdd, + bytes[] memory permittedAuthMethodPubkeysToAdd, + uint256[][] calldata permittedAuthMethodScopesToAdd, + uint256[] memory permittedAuthMethodTypesToRemove, + bytes[] memory permittedAuthMethodIdsToRemove + ) public onlyPKPOwner(tokenId) { + require( + permittedAuthMethodTypesToAdd.length == + permittedAuthMethodIdsToAdd.length && + permittedAuthMethodIdsToAdd.length == + permittedAuthMethodPubkeysToAdd.length && + permittedAuthMethodPubkeysToAdd.length == + permittedAuthMethodScopesToAdd.length, + "Must have same number of auth methods, ids, pubkeys, and scopes to add" + ); + + require( + permittedAuthMethodTypesToRemove.length == + permittedAuthMethodIdsToRemove.length, + "Must have same number of auth methods and ids to remove" + ); + + for (uint256 i = 0; i < permittedAuthMethodTypesToAdd.length; i++) { + addPermittedAuthMethod( + tokenId, + LibPKPPermissionsStorage.AuthMethod( + permittedAuthMethodTypesToAdd[i], + permittedAuthMethodIdsToAdd[i], + permittedAuthMethodPubkeysToAdd[i] + ), + permittedAuthMethodScopesToAdd[i] + ); + } + + for (uint256 i = 0; i < permittedAuthMethodTypesToRemove.length; i++) { + removePermittedAuthMethod( + tokenId, + permittedAuthMethodTypesToRemove[i], + permittedAuthMethodIdsToRemove[i] + ); + } + } + /// Add a permitted auth method for a given pubkey function addPermittedAuthMethod( uint256 tokenId, - AuthMethod memory authMethod, + LibPKPPermissionsStorage.AuthMethod memory authMethod, uint256[] calldata scopes ) public onlyPKPOwner(tokenId) { uint256 authMethodId = getAuthMethodId( @@ -301,20 +383,22 @@ contract PKPPermissions is Ownable { ); // we need to ensure that someone with the same auth method type and id can't add a different pubkey - require( - authMethods[authMethodId].userPubkey.length == 0 || - keccak256(authMethods[authMethodId].userPubkey) == - keccak256(authMethod.userPubkey), - "Cannot add a different pubkey for the same auth method type and id" - ); + if (authMethod.authMethodType == uint(AuthMethodType.WEBAUTHN)) { + require( + s().authMethods[authMethodId].userPubkey.length == 0 || + keccak256(s().authMethods[authMethodId].userPubkey) == + keccak256(authMethod.userPubkey), + "Cannot add a different pubkey for the same auth method type and id" + ); + } - authMethods[authMethodId] = authMethod; + s().authMethods[authMethodId] = authMethod; - EnumerableSet.UintSet - storage newPermittedAuthMethods = permittedAuthMethods[tokenId]; + EnumerableSet.UintSet storage newPermittedAuthMethods = s() + .permittedAuthMethods[tokenId]; newPermittedAuthMethods.add(authMethodId); - EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[ + EnumerableSet.UintSet storage newPkpIds = s().authMethodToPkpIds[ authMethodId ]; newPkpIds.add(tokenId); @@ -322,7 +406,7 @@ contract PKPPermissions is Ownable { for (uint256 i = 0; i < scopes.length; i++) { uint256 scopeId = scopes[i]; - permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId); + s().permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId); emit PermittedAuthMethodScopeAdded( tokenId, @@ -348,11 +432,11 @@ contract PKPPermissions is Ownable { ) public onlyPKPOwner(tokenId) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - EnumerableSet.UintSet - storage newPermittedAuthMethods = permittedAuthMethods[tokenId]; + EnumerableSet.UintSet storage newPermittedAuthMethods = s() + .permittedAuthMethods[tokenId]; newPermittedAuthMethods.remove(authMethodId); - EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[ + EnumerableSet.UintSet storage newPkpIds = s().authMethodToPkpIds[ authMethodId ]; newPkpIds.remove(tokenId); @@ -368,7 +452,7 @@ contract PKPPermissions is Ownable { ) public onlyPKPOwner(tokenId) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId); + s().permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId); emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId); } @@ -381,7 +465,7 @@ contract PKPPermissions is Ownable { ) public onlyPKPOwner(tokenId) { uint256 authMethodId = getAuthMethodId(authMethodType, id); - permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId); + s().permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId); emit PermittedAuthMethodScopeRemoved( tokenId, @@ -399,7 +483,11 @@ contract PKPPermissions is Ownable { ) public { addPermittedAuthMethod( tokenId, - AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, ""), + LibPKPPermissionsStorage.AuthMethod( + uint256(AuthMethodType.ACTION), + ipfsCID, + "" + ), scopes ); } @@ -422,7 +510,7 @@ contract PKPPermissions is Ownable { ) public { addPermittedAuthMethod( tokenId, - AuthMethod( + LibPKPPermissionsStorage.AuthMethod( uint256(AuthMethodType.ADDRESS), abi.encodePacked(user), "" @@ -439,8 +527,9 @@ contract PKPPermissions is Ownable { ); } - function setPkpNftAddress(address newPkpNftAddress) public onlyOwner { - pkpNFT = PKPNFT(newPkpNftAddress); + function setContractResolver(address newResolverAddress) public onlyOwner { + s().contractResolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); } /** @@ -451,7 +540,7 @@ contract PKPPermissions is Ownable { uint256 group, bytes32 root ) public onlyPKPOwner(tokenId) { - _rootHashes[tokenId][group] = root; + s()._rootHashes[tokenId][group] = root; emit RootHashUpdated(tokenId, group, root); } @@ -464,7 +553,7 @@ contract PKPPermissions is Ownable { bytes32[] memory proof, bytes32 leaf ) public view returns (bool) { - bytes32 root = _rootHashes[tokenId][group]; + bytes32 root = s()._rootHashes[tokenId][group]; if (root == bytes32(0)) return false; return MerkleProof.verify(proof, root, leaf); } @@ -479,7 +568,7 @@ contract PKPPermissions is Ownable { bool[] memory proofFlags, bytes32[] memory leaves ) public view returns (bool) { - bytes32 root = _rootHashes[tokenId][group]; + bytes32 root = s()._rootHashes[tokenId][group]; if (root == bytes32(0)) return false; return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves); } @@ -514,4 +603,5 @@ contract PKPPermissions is Ownable { uint256 indexed group, bytes32 root ); + event ContractResolverAddressSet(address newResolverAddress); } diff --git a/contracts/lit-node/PaymentDelegation.sol b/contracts/lit-node/PaymentDelegation.sol new file mode 100644 index 0000000..6704857 --- /dev/null +++ b/contracts/lit-node/PaymentDelegation.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibStakingStorage } from "./Staking/LibStakingStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct PaymentDelegationArgs { + address owner; + address init; + bytes initCalldata; +} + +contract PaymentDelegation { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + PaymentDelegationArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/PaymentDelegation/LibPaymentDelegationStorage.sol b/contracts/lit-node/PaymentDelegation/LibPaymentDelegationStorage.sol new file mode 100644 index 0000000..70c9322 --- /dev/null +++ b/contracts/lit-node/PaymentDelegation/LibPaymentDelegationStorage.sol @@ -0,0 +1,37 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +library LibPaymentDelegationStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + bytes32 constant PAYMENT_DELEGATION_POSITION = + keccak256("payment_delegation.storage"); + + // this lets the app put restrictions on how much they want to pay in a given period, per user. + // this is set globally for each payer, but is applied on a per user basis. + // so if you had a restriction of 10 requests per 10 minutes, that means 1 million users can make 10 requests each in the 10 minute window for 10 million total requests in 10 minutes. + struct Restriction { + uint requestsPerPeriod; + uint periodSeconds; + } + + struct PaymentDelegationStorage { + mapping(address => EnumerableSet.AddressSet) payers; // maps user wallet to payer wallet + mapping(address => Restriction) restrictions; // maps payer wallet to restrictions. these are optional. + mapping(address => EnumerableSet.AddressSet) users; // maps payer wallet to user wallets + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (PaymentDelegationStorage storage storageStruct) + { + bytes32 position = PAYMENT_DELEGATION_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/PaymentDelegation/PaymentDelegationFacet.sol b/contracts/lit-node/PaymentDelegation/PaymentDelegationFacet.sol new file mode 100644 index 0000000..a54af56 --- /dev/null +++ b/contracts/lit-node/PaymentDelegation/PaymentDelegationFacet.sol @@ -0,0 +1,112 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; + +import { LibPaymentDelegationStorage } from "./LibPaymentDelegationStorage.sol"; + +// import "hardhat/console.sol"; + +contract PaymentDelegationFacet { + using EnumerableSet for EnumerableSet.AddressSet; + + /* ========== VIEWS ========== */ + function s() + internal + pure + returns (LibPaymentDelegationStorage.PaymentDelegationStorage storage) + { + return LibPaymentDelegationStorage.getStorage(); + } + + function getPayersAndRestrictions( + address[] memory users + ) + public + view + returns ( + address[][] memory, + LibPaymentDelegationStorage.Restriction[][] memory + ) + { + address[][] memory payers = new address[][](users.length); + LibPaymentDelegationStorage.Restriction[][] + memory restrictions = new LibPaymentDelegationStorage.Restriction[][]( + users.length + ); + for (uint i = 0; i < users.length; i++) { + payers[i] = s().payers[users[i]].values(); + LibPaymentDelegationStorage.Restriction[] + memory tempRestrictionsArray = new LibPaymentDelegationStorage.Restriction[]( + payers[i].length + ); + for (uint j = 0; j < payers[i].length; j++) { + tempRestrictionsArray[j] = s().restrictions[payers[i][j]]; + } + restrictions[i] = tempRestrictionsArray; + } + return (payers, restrictions); + } + + function getUsers(address payer) public view returns (address[] memory) { + return s().users[payer].values(); + } + + function getRestriction( + address payer + ) public view returns (LibPaymentDelegationStorage.Restriction memory) { + return s().restrictions[payer]; + } + + function getPayers(address user) public view returns (address[] memory) { + return s().payers[user].values(); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + function delegatePayments(address user) public { + s().payers[user].add(msg.sender); // this guarantees the auth - that the payer made this txn, because msg.sender is authed. + s().users[msg.sender].add(user); + } + + function undelegatePayments(address user) public { + require( + s().payers[user].contains(msg.sender), + "not authorized to undelegate payments" + ); + s().payers[user].remove(msg.sender); + s().users[msg.sender].remove(user); + } + + function delegatePaymentsBatch(address[] memory users) public { + for (uint i = 0; i < users.length; i++) { + s().payers[users[i]].add(msg.sender); + s().users[msg.sender].add(users[i]); + } + } + + function undelegatePaymentsBatch(address[] memory users) public { + for (uint i = 0; i < users.length; i++) { + require( + s().payers[users[i]].contains(msg.sender), + "not authorized to undelegate payments" + ); + s().payers[users[i]].remove(msg.sender); + s().users[msg.sender].remove(users[i]); + } + } + + function setRestriction( + LibPaymentDelegationStorage.Restriction memory r + ) public { + s().restrictions[msg.sender] = r; + } + + /* ========== EVENTS ========== */ + + event RestrictionSet( + address indexed payer, + LibPaymentDelegationStorage.Restriction restriction + ); +} diff --git a/contracts/lit-node/PubkeyRouter.sol b/contracts/lit-node/PubkeyRouter.sol new file mode 100644 index 0000000..7e8835a --- /dev/null +++ b/contracts/lit-node/PubkeyRouter.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibPubkeyRouterStorage } from "./PubkeyRouter/LibPubkeyRouterStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct PubkeyRouterArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract PubkeyRouter { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + PubkeyRouterArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibPubkeyRouterStorage.getStorage().contractResolver = ContractResolver( + _args.contractResolver + ); + LibPubkeyRouterStorage.getStorage().env = _args.env; + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/PubkeyRouter/LibPubkeyRouterStorage.sol b/contracts/lit-node/PubkeyRouter/LibPubkeyRouterStorage.sol new file mode 100644 index 0000000..8617700 --- /dev/null +++ b/contracts/lit-node/PubkeyRouter/LibPubkeyRouterStorage.sol @@ -0,0 +1,66 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +interface IPubkeyRouter { + struct RootKey { + bytes pubkey; + uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. + } + + struct Signature { + bytes32 r; + bytes32 s; + uint8 v; + } +} + +library LibPubkeyRouterStorage { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.Bytes32Set; + using EnumerableSet for EnumerableSet.UintSet; + using BytesLib for bytes; + using BitMaps for BitMaps.BitMap; + + bytes32 constant PUBKEY_ROUTER_POSITION = keccak256("pubkeyrouter.storage"); + + struct PubkeyRoutingData { + bytes pubkey; + uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. + bytes32 derivedKeyId; + } + + struct VoteToRegisterRootKey { + uint256 votes; + mapping(address => bool) voted; + } + + struct PubkeyRouterStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + // map staking address -> uncompressed pubkey -> VoteToRegisterRootKey + mapping(address => mapping(bytes => VoteToRegisterRootKey)) votesToRegisterRootKeys; + // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData + mapping(uint256 => PubkeyRoutingData) pubkeys; + // map the eth address to a pkp id + mapping(address => uint256) ethAddressToPkpId; + // map staking contract to root keys + mapping(address => IPubkeyRouter.RootKey[]) rootKeys; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (PubkeyRouterStorage storage storageStruct) + { + bytes32 position = PUBKEY_ROUTER_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/PubkeyRouter/PubkeyRouterFacet.sol b/contracts/lit-node/PubkeyRouter/PubkeyRouterFacet.sol new file mode 100644 index 0000000..e5303bb --- /dev/null +++ b/contracts/lit-node/PubkeyRouter/PubkeyRouterFacet.sol @@ -0,0 +1,314 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; + +import { PKPNFT } from "../PKPNFT.sol"; +import { Staking } from "../Staking.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { IKeyDeriver } from "../HDKeyDeriver.sol"; +import { StakingFacet } from "../Staking/StakingFacet.sol"; +import { StakingViewsFacet } from "../Staking/StakingViewsFacet.sol"; +import { PKPNFTFacet } from "../PKPNFT/PKPNFTFacet.sol"; + +import { LibPubkeyRouterStorage, IPubkeyRouter } from "./LibPubkeyRouterStorage.sol"; + +import "hardhat/console.sol"; + +// TODO: make the tests send PKPNFT into the constructor +// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it +// TODO: setRoutingData() for a batch of keys + +contract PubkeyRouterFacet { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.Bytes32Set; + using EnumerableSet for EnumerableSet.UintSet; + using BytesLib for bytes; + + /* ========== Errors ========== */ + error CallerNotOwner(); + + /* ========== Modifiers ========== */ + modifier onlyPKPOwner(uint256 tokenId) { + // check that user is allowed to set this + PKPNFTFacet pkpNFT = PKPNFTFacet(getPkpNftAddress()); + address nftOwner = pkpNFT.ownerOf(tokenId); + require(msg.sender == nftOwner, "Not PKP NFT owner"); + _; + } + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + + function s() + internal + pure + returns (LibPubkeyRouterStorage.PubkeyRouterStorage storage) + { + return LibPubkeyRouterStorage.getStorage(); + } + + function ethAddressToPkpId( + address ethAddress + ) public view returns (uint256) { + return s().ethAddressToPkpId[ethAddress]; + } + + function pubkeys( + uint256 tokenId + ) public view returns (LibPubkeyRouterStorage.PubkeyRoutingData memory) { + return s().pubkeys[tokenId]; + } + + function getPkpNftAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.PKP_NFT_CONTRACT(), + s().env + ); + } + + /// get root keys for a given staking contract + function getRootKeys( + address stakingContract + ) public view returns (IPubkeyRouter.RootKey[] memory) { + return s().rootKeys[stakingContract]; + } + + /// get the routing data for a given key hash + function getRoutingData( + uint256 tokenId + ) external view returns (LibPubkeyRouterStorage.PubkeyRoutingData memory) { + return s().pubkeys[tokenId]; + } + + /// get if a given pubkey has routing data associated with it or not + function isRouted(uint256 tokenId) public view returns (bool) { + LibPubkeyRouterStorage.PubkeyRoutingData memory prd = s().pubkeys[ + tokenId + ]; + return + prd.pubkey.length != 0 && + prd.keyType != 0 && + prd.derivedKeyId != bytes32(0); + } + + /// get the eth address for the keypair, as long as it's an ecdsa keypair + function getEthAddress(uint256 tokenId) public view returns (address) { + return deriveEthAddressFromPubkey(s().pubkeys[tokenId].pubkey); + } + + /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress + function getPubkey(uint256 tokenId) public view returns (bytes memory) { + return s().pubkeys[tokenId].pubkey; + } + + function deriveEthAddressFromPubkey( + bytes memory pubkey + ) public pure returns (address) { + // remove 0x04 prefix + bytes32 hashed = keccak256(pubkey.slice(1, 64)); + return address(uint160(uint256(hashed))); + } + + function checkNodeSignatures( + IPubkeyRouter.Signature[] memory signatures, + bytes memory signedMessage, + address stakingContractAddress + ) public view returns (bool) { + StakingViewsFacet stakingContract = StakingViewsFacet( + stakingContractAddress + ); + require( + signatures.length >= + stakingContract.currentValidatorCountForConsensus(), + "PubkeyRouter: incorrect number of signatures on a given root key" + ); + for (uint256 i = 0; i < signatures.length; i++) { + IPubkeyRouter.Signature memory sig = signatures[i]; + address signer = ECDSA.recover( + ECDSA.toEthSignedMessageHash(signedMessage), + sig.v, + sig.r, + sig.s + ); + // console.log("signer: "); + // console.log(signer); + require( + stakingContract.isActiveValidatorByNodeAddress(signer), + "PubkeyRouter: signer is not active validator" + ); + } + return true; + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /// register a pubkey and routing data for a given key hash + function setRoutingData( + uint256 tokenId, + bytes memory pubkey, + address stakingContractAddress, + uint256 keyType, + bytes32 derivedKeyId + ) public { + require( + msg.sender == address(getPkpNftAddress()), + "setRoutingData must be called by PKPNFT contract" + ); + + require( + tokenId == uint256(keccak256(pubkey)), + "tokenId does not match hashed pubkey" + ); + require( + !isRouted(tokenId), + "PubkeyRouter: pubkey already has routing data" + ); + + s().pubkeys[tokenId].pubkey = pubkey; + s().pubkeys[tokenId].keyType = keyType; + s().pubkeys[tokenId].derivedKeyId = derivedKeyId; + + address pkpAddress = deriveEthAddressFromPubkey(pubkey); + s().ethAddressToPkpId[pkpAddress] = tokenId; + + emit PubkeyRoutingDataSet( + tokenId, + pubkey, + stakingContractAddress, + keyType, + derivedKeyId + ); + } + + /// Set the pubkey and routing data for a given key hash + // this is only used by an admin in case of emergency. can prob be removed. + function setRoutingDataAsAdmin( + uint256 tokenId, + bytes memory pubkey, + address stakingContract, + uint256 keyType, + bytes32 derivedKeyId + ) public onlyOwner { + s().pubkeys[tokenId].pubkey = pubkey; + s().pubkeys[tokenId].keyType = keyType; + s().pubkeys[tokenId].derivedKeyId = derivedKeyId; + + address pkpAddress = deriveEthAddressFromPubkey(pubkey); + s().ethAddressToPkpId[pkpAddress] = tokenId; + + emit PubkeyRoutingDataSet( + tokenId, + pubkey, + stakingContract, + keyType, + derivedKeyId + ); + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + s().contractResolver = ContractResolver(newResolverAddress); + emit ContractResolverAddressSet(newResolverAddress); + } + + function voteForRootKeys( + address stakingContractAddress, + IPubkeyRouter.RootKey[] memory newRootKeys + ) public { + StakingViewsFacet stakingContract = StakingViewsFacet( + stakingContractAddress + ); + require( + stakingContract.isActiveValidatorByNodeAddress(msg.sender), + "PubkeyRouter: txn sender is not active validator" + ); + + require( + s().rootKeys[stakingContractAddress].length == 0, + "PubkeyRouter: root keys already set for this staking contract" + ); + + // record the votes + for (uint i = 0; i < newRootKeys.length; i++) { + IPubkeyRouter.RootKey memory rootKey = newRootKeys[i]; + require( + s() + .votesToRegisterRootKeys[stakingContractAddress][rootKey.pubkey] + .voted[msg.sender] == false, + "PubkeyRouter: validator has already voted for this root key" + ); + s() + .votesToRegisterRootKeys[stakingContractAddress][rootKey.pubkey] + .votes += 1; + s() + .votesToRegisterRootKeys[stakingContractAddress][rootKey.pubkey] + .voted[msg.sender] = true; + + // if it has enough votes, register it + if ( + s() + .votesToRegisterRootKeys[stakingContractAddress][rootKey.pubkey] + .votes == + stakingContract.getValidatorsInCurrentEpochLength() + ) { + s().rootKeys[stakingContractAddress].push(rootKey); + emit RootKeySet(stakingContractAddress, rootKey); + } + } + } + + function getDerivedPubkey( + address stakingContract, + bytes32 derivedKeyId + ) public view returns (bytes memory) { + IPubkeyRouter.RootKey[] memory rootPubkeys = getRootKeys( + stakingContract + ); + + bytes memory pubkey = _computeHDPubkey(derivedKeyId, rootPubkeys, 2); + + return pubkey; + } + + function adminResetRootKeys(address stakingContract) public onlyOwner { + require(s().env == ContractResolver.Env.Dev, "only for dev env"); + + delete s().rootKeys[stakingContract]; + } + + function _computeHDPubkey( + bytes32 derivedKeyId, + IPubkeyRouter.RootKey[] memory rootHDKeys, + uint256 keyType + ) internal view returns (bytes memory) { + address deriverAddr = s().contractResolver.getContract( + s().contractResolver.HD_KEY_DERIVER_CONTRACT(), + s().env + ); + (bool success, bytes memory pubkey) = IKeyDeriver(deriverAddr) + .computeHDPubKey(derivedKeyId, rootHDKeys, keyType); + + require(success, "PubkeyRouter: Failed public key calculation"); + return pubkey; + } + + /* ========== EVENTS ========== */ + + event PubkeyRoutingDataSet( + uint256 indexed tokenId, + bytes pubkey, + address stakingContract, + uint256 keyType, + bytes32 derivedKeyId + ); + event ContractResolverAddressSet(address newResolverAddress); + event RootKeySet(address stakingContract, IPubkeyRouter.RootKey rootKey); +} diff --git a/contracts/lit-node/RateLimitNFT.sol b/contracts/lit-node/RateLimitNFT.sol new file mode 100644 index 0000000..cdfba48 --- /dev/null +++ b/contracts/lit-node/RateLimitNFT.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibRateLimitNFTStorage } from "./RateLimitNFT/LibRateLimitNFTStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct StakingArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract RateLimitNFT { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + StakingArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibRateLimitNFTStorage.getStorage().contractResolver = ContractResolver( + _args.contractResolver + ); + LibRateLimitNFTStorage.getStorage().env = _args.env; + + LibRateLimitNFTStorage + .getStorage() + .additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei + // 24 hours in seconds + LibRateLimitNFTStorage.getStorage().defaultRateLimitWindowSeconds = + 60 * + 60 * + 24; + // 24 hours in seconds + LibRateLimitNFTStorage.getStorage().RLIHolderRateLimitWindowSeconds = + 60 * + 60 * + 24; + LibRateLimitNFTStorage.getStorage().freeRequestsPerRateLimitWindow = 0; + LibRateLimitNFTStorage.getStorage().maxRequestsPerKilosecond = 10000; + LibRateLimitNFTStorage.getStorage().maxExpirationSeconds = 2592000; // 1 month in seconds + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/RateLimitNFT/LibRateLimitNFTStorage.sol b/contracts/lit-node/RateLimitNFT/LibRateLimitNFTStorage.sol new file mode 100644 index 0000000..dbe2cc8 --- /dev/null +++ b/contracts/lit-node/RateLimitNFT/LibRateLimitNFTStorage.sol @@ -0,0 +1,47 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +library LibRateLimitNFTStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + struct RateLimit { + uint256 requestsPerKilosecond; + uint256 expiresAt; + } + + bytes32 constant RATELIMIT_NFT_POSITION = keccak256("ratelimitnft.storage"); + + struct RateLimitNFTStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + address freeMintSigner; + uint256 additionalRequestsPerKilosecondCost; + uint256 tokenIdCounter; + uint256 defaultRateLimitWindowSeconds; + uint256 RLIHolderRateLimitWindowSeconds; + uint256 freeRequestsPerRateLimitWindow; + mapping(uint256 => RateLimit) capacity; + mapping(bytes32 => bool) redeemedFreeMints; + uint256 maxRequestsPerKilosecond; + uint256 maxExpirationSeconds; + // maps midnight timestamps (divisible by 86400) to the total requests sold that will expire at that time + mapping(uint256 => uint256) totalSoldRequestsPerKilosecondByExpirationTime; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (RateLimitNFTStorage storage storageStruct) + { + bytes32 position = RATELIMIT_NFT_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/RateLimitNFT/RateLimitNFTFacet.sol b/contracts/lit-node/RateLimitNFT/RateLimitNFTFacet.sol new file mode 100644 index 0000000..88a89c3 --- /dev/null +++ b/contracts/lit-node/RateLimitNFT/RateLimitNFTFacet.sol @@ -0,0 +1,262 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ERC721Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/ERC721Upgradeable.sol"; +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { ERC721BurnableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; +import { ERC721EnumerableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; +import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; +import { ReentrancyGuardUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/security/ReentrancyGuardUpgradeable.sol"; +import { ERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/ERC165Upgradeable.sol"; +import { IERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/IERC165Upgradeable.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { LibRateLimitNFTStorage } from "./LibRateLimitNFTStorage.sol"; +import { RateLimitNFTViewsFacet } from "./RateLimitNFTViewsFacet.sol"; + +import "hardhat/console.sol"; + +/// @title Rate Limit NFT +/// +/// @dev This is the contract for the Rate Limit NFTs +/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit +/// And how it works, is that you can buy X requestsPerKilosecond over a period of time +/// 1 requestsPerKilosecond = 0.001 requests per second and +/// 1000 requestsPerKilosecond = 1 request per second +contract RateLimitNFTFacet is + ERC721Upgradeable, + ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable, + ReentrancyGuardUpgradeable +{ + using Strings for uint256; + + error CallerNotOwner(); + + function initialize() public initializer { + __ERC721_init("Rate Limit Increases on Lit Protocol", "RLI"); + } + + /* ========== Modifiers ========== */ + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + function s() + internal + pure + returns (LibRateLimitNFTStorage.RateLimitNFTStorage storage) + { + return LibRateLimitNFTStorage.getStorage(); + } + + function views() internal view returns (RateLimitNFTViewsFacet) { + return RateLimitNFTViewsFacet(address(this)); + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface( + bytes4 interfaceId + ) + public + view + virtual + override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + returns (bool) + { + return + super.supportsInterface(interfaceId) || + LibDiamond.diamondStorage().supportedInterfaces[interfaceId]; + } + + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId, + uint256 batchSize + ) + internal + virtual + override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + { + ERC721EnumerableUpgradeable._beforeTokenTransfer( + from, + to, + tokenId, + batchSize + ); + } + + function tokenURI( + uint256 tokenId + ) public view override returns (string memory) { + return views().tokenSVG(tokenId); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function. + function mint(uint256 expiresAt) public payable returns (uint256) { + s().tokenIdCounter++; + uint256 tokenId = s().tokenIdCounter; + + uint256 requestsPerKilosecond = views().calculateRequestsPerKilosecond( + msg.value, + expiresAt + ); + + // sanity check + uint256 cost = views().calculateCost(requestsPerKilosecond, expiresAt); + + require( + msg.value > 0 && msg.value >= cost, + "You must send the cost of this rate limit increase. To check the cost, use the calculateCost function." + ); + require(cost > 0, "The cost must be greater than 0"); + + _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt); + + return tokenId; + } + + function freeMint( + uint256 expiresAt, + uint256 requestsPerKilosecond, + bytes32 msgHash, + uint8 v, + bytes32 r, + bytes32 sVal + ) public returns (uint256) { + s().tokenIdCounter++; + uint256 tokenId = s().tokenIdCounter; + + // this will panic if the sig is bad + views().freeMintSigTest( + expiresAt, + requestsPerKilosecond, + msgHash, + v, + r, + sVal + ); + s().redeemedFreeMints[msgHash] = true; + + _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt); + + return tokenId; + } + + function _mintWithoutValueCheck( + uint256 tokenId, + uint256 requestsPerKilosecond, + uint256 expiresAt + ) internal { + require( + expiresAt < block.timestamp + s().maxExpirationSeconds, + "You cannot purchase an expiration time that is more than the maxExpirationSeconds in the future" + ); + require(expiresAt > block.timestamp, "Expiration time is in the past"); + + // Check that it's midnight. A day in Unix timestamp is 86400 seconds, so if a timestamp is at + // midnight, it should be divisible by 86400 with no remainder. + require( + expiresAt % 86400 == 0, + "Expiration time must be set to midnight on any given day" + ); + require( + views().checkBelowMaxRequestsPerKilosecond(requestsPerKilosecond), + "Can't allocate capacity beyond the global max requests per kilosecond" + ); + _safeMint(msg.sender, tokenId); + s().capacity[tokenId] = LibRateLimitNFTStorage.RateLimit( + requestsPerKilosecond, + expiresAt + ); + // insert into total sold mapping + s().totalSoldRequestsPerKilosecondByExpirationTime[ + expiresAt + ] += requestsPerKilosecond; + } + + function setAdditionalRequestsPerKilosecondCost( + uint256 newAdditionalRequestsPerKilosecondCost + ) public onlyOwner { + s() + .additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost; + emit AdditionalRequestsPerKilosecondCostSet( + newAdditionalRequestsPerKilosecondCost + ); + } + + function setFreeMintSigner(address newFreeMintSigner) public onlyOwner { + s().freeMintSigner = newFreeMintSigner; + emit FreeMintSignerSet(newFreeMintSigner); + } + + function withdraw() public onlyOwner nonReentrant { + uint256 withdrawAmount = address(this).balance; + (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); + require(sent); + emit Withdrew(withdrawAmount); + } + + function setRateLimitWindowSeconds( + uint256 newRateLimitWindowSeconds + ) public onlyOwner { + s().defaultRateLimitWindowSeconds = newRateLimitWindowSeconds; + emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds); + } + + function setRLIHolderRateLimitWindowSeconds( + uint256 newRLIHolderRateLimitWindowSeconds + ) public onlyOwner { + s() + .RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds; + emit RLIHolderRateLimitWindowSecondsSet( + newRLIHolderRateLimitWindowSeconds + ); + } + + function setFreeRequestsPerRateLimitWindow( + uint256 newFreeRequestsPerRateLimitWindow + ) public onlyOwner { + s().freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow; + emit FreeRequestsPerRateLimitWindowSet( + newFreeRequestsPerRateLimitWindow + ); + } + + function setMaxRequestsPerKilosecond( + uint256 newMaxRequestsPerKilosecond + ) public onlyOwner { + s().maxRequestsPerKilosecond = newMaxRequestsPerKilosecond; + } + + function setMaxExpirationSeconds( + uint256 newMaxExpirationSeconds + ) public onlyOwner { + s().maxExpirationSeconds = newMaxExpirationSeconds; + } + + /* ========== EVENTS ========== */ + + event AdditionalRequestsPerKilosecondCostSet( + uint256 newAdditionalRequestsPerKilosecondCost + ); + event FreeMintSignerSet(address indexed newFreeMintSigner); + event Withdrew(uint256 amount); + event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds); + event RLIHolderRateLimitWindowSecondsSet( + uint256 newRLIHolderRateLimitWindowSeconds + ); + event FreeRequestsPerRateLimitWindowSet( + uint256 newFreeRequestsPerRateLimitWindow + ); +} diff --git a/contracts/lit-node/RateLimitNFT/RateLimitNFTViewsFacet.sol b/contracts/lit-node/RateLimitNFT/RateLimitNFTViewsFacet.sol new file mode 100644 index 0000000..2bdea77 --- /dev/null +++ b/contracts/lit-node/RateLimitNFT/RateLimitNFTViewsFacet.sol @@ -0,0 +1,256 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ERC721Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/ERC721Upgradeable.sol"; +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { ERC721BurnableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; +import { ERC721EnumerableUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; +import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; +import { ReentrancyGuardUpgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/security/ReentrancyGuardUpgradeable.sol"; +import { ERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/ERC165Upgradeable.sol"; +import { IERC165Upgradeable } from "@gnus.ai/contracts-upgradeable-diamond/contracts/utils/introspection/IERC165Upgradeable.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { LibRateLimitNFTStorage } from "./LibRateLimitNFTStorage.sol"; + +import "hardhat/console.sol"; + +/// @title Rate Limit NFT +/// +/// @dev This is the contract for the Rate Limit NFTs +/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit +/// And how it works, is that you can buy X requestsPerKilosecond over a period of time +/// 1 requestsPerKilosecond = 0.001 requests per second and +/// 1000 requestsPerKilosecond = 1 request per second +contract RateLimitNFTViewsFacet { + using Strings for uint256; + + /* ========== VIEWS ========== */ + + function viewStorage() + internal + pure + returns (LibRateLimitNFTStorage.RateLimitNFTStorage storage) + { + return LibRateLimitNFTStorage.getStorage(); + } + + function freeMintSigner() public view returns (address) { + return viewStorage().freeMintSigner; + } + + function additionalRequestsPerKilosecondCost() + public + view + returns (uint256) + { + return viewStorage().additionalRequestsPerKilosecondCost; + } + + function tokenIdCounter() public view returns (uint256) { + return viewStorage().tokenIdCounter; + } + + function defaultRateLimitWindowSeconds() public view returns (uint256) { + return viewStorage().defaultRateLimitWindowSeconds; + } + + function RLIHolderRateLimitWindowSeconds() public view returns (uint256) { + return viewStorage().RLIHolderRateLimitWindowSeconds; + } + + function freeRequestsPerRateLimitWindow() public view returns (uint256) { + return viewStorage().freeRequestsPerRateLimitWindow; + } + + function capacity( + uint256 tokenId + ) public view returns (LibRateLimitNFTStorage.RateLimit memory) { + return viewStorage().capacity[tokenId]; + } + + function redeemedFreeMints(bytes32 msgHash) public view returns (bool) { + return viewStorage().redeemedFreeMints[msgHash]; + } + + /// throws if the sig is bad or msg doesn't match + function freeMintSigTest( + uint256 expiresAt, + uint256 requestsPerKilosecond, + bytes32 msgHash, + uint8 v, + bytes32 r, + bytes32 sVal + ) public view { + // make sure the msgHash matches the tokenId + // if these don't match, the user could use any old signature + // to mint any number of PKPs + // and this would be vulnerable to replay attacks + // FIXME this needs the whole "ethereum signed message: \27" thingy prepended to actually work + bytes32 expectedHash = prefixed( + keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond)) + ); + require( + expectedHash == msgHash, + "The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!" + ); + + // make sure it was actually signed by freeMintSigner + address recovered = ecrecover(msgHash, v, r, sVal); + require( + recovered == viewStorage().freeMintSigner, + "This freeMint was not signed by freeMintSigner. How embarassing." + ); + + // make sure it hasn't already been redeemed + require( + !viewStorage().redeemedFreeMints[msgHash], + "This freeMint has already been redeemed. How embarassing." + ); + } + + function calculateCost( + uint256 requestsPerKilosecond, + uint256 expiresAt + ) public view returns (uint256) { + require( + requestsPerKilosecond > 0, + "The requestsPerKilosecond must be greater than 0" + ); + require( + expiresAt < block.timestamp + viewStorage().maxExpirationSeconds, + "You cannot purchase an expiration time that is more than the maxExpirationSeconds in the future" + ); + require(expiresAt > block.timestamp, "Expiration time is in the past"); + + // Check that it's midnight. A day in Unix timestamp is 86400 seconds, so if a timestamp is at + // midnight, it should be divisible by 86400 with no remainder. + require( + expiresAt % 86400 == 0, + "Expiration time must be set to midnight on any given day" + ); + + // calculate the duration + uint256 durationInSeconds = (expiresAt - block.timestamp); + + // calculate the cost + uint256 cost = (requestsPerKilosecond * + durationInSeconds * + viewStorage().additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000 + + return cost; + } + + function calculateRequestsPerKilosecond( + uint256 payingAmount, + uint256 expiresAt + ) public view returns (uint256) { + require(payingAmount > 0, "You must pay more than 0"); + require( + expiresAt > block.timestamp, + "The expiresAt must be in the future" + ); + require( + expiresAt - block.timestamp < viewStorage().maxExpirationSeconds, + "You cannot purchase an expiration time that is more than the maxExpirationSeconds in the future" + ); + // Check that it's midnight. A day in Unix timestamp is 86400 seconds, so if a timestamp is at + // midnight, it should be divisible by 86400 with no remainder. + require( + expiresAt % 86400 == 0, + "Expiration time must be set to midnight on any given day" + ); + + // calculate the duration + uint256 durationInSeconds = (expiresAt - block.timestamp); + // console.log("durationInSeconds: "); + // console.log(durationInSeconds); + + // calculate the cost + uint256 requestsPerKilosecond = payingAmount / + ((durationInSeconds * + viewStorage().additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000 + + return requestsPerKilosecond; + } + + function tokenSVG(uint256 tokenId) public view returns (string memory) { + string + memory svgData = ""; + + string memory json = Base64.encode( + bytes( + string( + abi.encodePacked( + '{"name": "Lit Protocol Rate Limit Increase", "description": "This NFT entitles the holder to a rate limit increase on the Lit Protocol Network", "image_data": "', + bytes(svgData), + '","attributes": [{"display_type": "date", "trait_type": "Expiration Date", "value": ', + viewStorage().capacity[tokenId].expiresAt.toString(), + '}, {"display_type": "number", "trait_type": "Millirequests Per Second", "value": ', + viewStorage() + .capacity[tokenId] + .requestsPerKilosecond + .toString(), + "}]}" + ) + ) + ) + ); + return string(abi.encodePacked("data:application/json;base64,", json)); + } + + function isExpired(uint256 tokenId) public view returns (bool) { + return viewStorage().capacity[tokenId].expiresAt <= block.timestamp; + } + + // Builds a prefixed hash to mimic the behavior of eth_sign. + function prefixed(bytes32 hash) public pure returns (bytes32) { + return + keccak256( + abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) + ); + } + + function maxRequestsPerKilosecond() public view returns (uint256) { + return viewStorage().maxRequestsPerKilosecond; + } + + function maxExpirationSeconds() public view returns (uint256) { + return viewStorage().maxExpirationSeconds; + } + + // sum up all unexpired sold requests per kilosecond + function currentSoldRequestsPerKilosecond() public view returns (uint256) { + uint256 totalRequestsPerKilosecond; + uint256 midnightTonight = (block.timestamp / 86400 + 1) * 86400; + uint256 iterations = viewStorage().maxExpirationSeconds / 86400; + for (uint256 i = 0; i < iterations; i++) { + totalRequestsPerKilosecond += viewStorage() + .totalSoldRequestsPerKilosecondByExpirationTime[ + midnightTonight + (i * 86400) + ]; + } + return totalRequestsPerKilosecond; + } + + // this function should return true if the requestedRequestsPerKilosecond + the current sold requests is < the maxRequestsPerKilosecond + function checkBelowMaxRequestsPerKilosecond( + uint256 requestedRequestsPerKilosecond + ) public view returns (bool) { + uint256 totalRequestsPerKilosecond = currentSoldRequestsPerKilosecond(); + return + totalRequestsPerKilosecond + requestedRequestsPerKilosecond < + viewStorage().maxRequestsPerKilosecond; + } + + function totalSoldRequestsPerKilosecondByExpirationTime( + uint256 expiresAt + ) public view returns (uint256) { + return + viewStorage().totalSoldRequestsPerKilosecondByExpirationTime[ + expiresAt + ]; + } +} diff --git a/contracts/lit-node/Staking.sol b/contracts/lit-node/Staking.sol new file mode 100644 index 0000000..3bc6bab --- /dev/null +++ b/contracts/lit-node/Staking.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibStakingStorage } from "./Staking/LibStakingStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct StakingArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract Staking { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + StakingArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibStakingStorage.getStorage().contractResolver = ContractResolver( + _args.contractResolver + ); + LibStakingStorage.getStorage().env = _args.env; + + // 0.05 tokens per token staked meaning a 5% per epoch inflation rate + uint256[] memory keyTypesTemp = new uint256[](2); + keyTypesTemp[0] = 1; + keyTypesTemp[1] = 2; + + LibStakingStorage.getStorage().configs[0] = LibStakingStorage.Config({ + tokenRewardPerTokenPerEpoch: (10 ** 18) / 20, // 18 decimal places in token + DEPRECATED_complaintTolerance: 10, + DEPRECATED_complaintIntervalSecs: 900, + keyTypes: keyTypesTemp, + minimumValidatorCount: 3, + maxConcurrentRequests: 1000, + maxTripleCount: 25, + minTripleCount: 10, + peerCheckingIntervalSecs: 10000, + maxTripleConcurrency: 2, + rpcHealthcheckEnabled: true + }); + uint256 epochLengthSeconds = 1; + LibStakingStorage.getStorage().epochs[0] = LibStakingStorage.Epoch({ + epochLength: epochLengthSeconds, + number: 1, + endTime: block.timestamp + epochLengthSeconds, + retries: 0, + timeout: 60 + }); + LibStakingStorage.getStorage().state = LibStakingStorage.States.Paused; + + // set sane defaults for min and max version + LibStakingStorage.getStorage().versionRequirements[ + 0 + ] = LibStakingStorage.Version({ major: 0, minor: 0, patch: 0 }); + LibStakingStorage.getStorage().versionRequirements[ + 1 + ] = LibStakingStorage.Version({ major: 10000, minor: 0, patch: 0 }); + + // Set up complaint configs + // Unresponsive reasons - 1 + LibStakingStorage.getStorage().complaintReasonToConfig[ + 1 + ] = LibStakingStorage.ComplaintConfig({ + tolerance: 6, + intervalSecs: 90, + kickPenaltyPercent: 5 + }); + // Non-Participation reasons - 2 + LibStakingStorage.getStorage().complaintReasonToConfig[ + 2 + ] = LibStakingStorage.ComplaintConfig({ + tolerance: 10, + intervalSecs: 90, + kickPenaltyPercent: 5 + }); + // Incorrect info - 3 + LibStakingStorage.getStorage().complaintReasonToConfig[ + 3 + ] = LibStakingStorage.ComplaintConfig({ + tolerance: 10, + intervalSecs: 90, + kickPenaltyPercent: 5 + }); + // Unknown error - 4 (not used right now, but just in case) + LibStakingStorage.getStorage().complaintReasonToConfig[ + 4 + ] = LibStakingStorage.ComplaintConfig({ + tolerance: 10, + intervalSecs: 90, + kickPenaltyPercent: 5 + }); + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/Staking/LibStakingStorage.sol b/contracts/lit-node/Staking/LibStakingStorage.sol new file mode 100644 index 0000000..f7d0bb8 --- /dev/null +++ b/contracts/lit-node/Staking/LibStakingStorage.sol @@ -0,0 +1,151 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +interface IPubkeyRouter { + struct RootKey { + bytes pubkey; + uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. + } + + struct Signature { + bytes32 r; + bytes32 s; + uint8 v; + } +} + +library LibStakingStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + bytes32 constant STAKING_POSITION = keccak256("staking.storage"); + + enum States { + Active, + NextValidatorSetLocked, + ReadyForNextEpoch, + Unlocked, + Paused, + Restore + } + + struct Validator { + uint32 ip; + uint128 ipv6; + uint32 port; + address nodeAddress; + uint256 reward; + uint256 senderPubKey; + uint256 receiverPubKey; + } + + struct AddressMapping { + address nodeAddress; + address stakerAddress; + } + + struct VoteToKickValidatorInNextEpoch { + uint256 votes; + mapping(address => bool) voted; + } + + struct Epoch { + uint256 epochLength; // in seconds + uint256 number; // the current epoch number + uint256 endTime; // the end timestamp where the next epoch can be kicked off + uint256 retries; // incremented upon failure to advance and subsequent unlock + uint256 timeout; // timeout in seconds, where the nodes can be unlocked. + } + + struct Config { + uint256 tokenRewardPerTokenPerEpoch; + /// @notice Use complaintReasonToConfig instead. + uint256 DEPRECATED_complaintTolerance; // cycles after which to escalate peer complaints to chain + /// @notice Use complaintReasonToConfig instead. + uint256 DEPRECATED_complaintIntervalSecs; + // the key type of the node. // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying. + uint256[] keyTypes; + // don't start the DKG or let nodes leave the validator set + // if there are less than this many nodes + uint256 minimumValidatorCount; + uint256 maxConcurrentRequests; + uint256 maxTripleCount; + uint256 minTripleCount; + uint256 peerCheckingIntervalSecs; + uint256 maxTripleConcurrency; + bool rpcHealthcheckEnabled; + } + + struct ComplaintConfig { + uint256 tolerance; + uint256 intervalSecs; + uint256 kickPenaltyPercent; + } + + struct Version { + uint256 major; + uint256 minor; + uint256 patch; + } + + struct StakingStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + States state; + EnumerableSet.AddressSet validatorsInCurrentEpoch; + EnumerableSet.AddressSet validatorsInNextEpoch; + EnumerableSet.AddressSet validatorsKickedFromNextEpoch; + uint256 totalStaked; + // versionRequirements[0] is the min version + // versionRequirements[1] is the max version + mapping(uint256 => Version) versionRequirements; + // storing this in a mapping so that it can be changed in the future + // always use epochs[0] + mapping(uint256 => Epoch) epochs; + // storing this in a mapping so that it can be changed in the future. + // always use configs[0] + mapping(uint256 => Config) configs; + // list of all validators, even ones that are not in the current or next epoch + // maps STAKER address to Validator struct + mapping(address => Validator) validators; + // stakers join by staking, but nodes need to be able to vote to kick. + // to avoid node operators having to run a hotwallet with their staking private key, + // the node gets it's own private key that it can use to vote to kick, + // or signal that the next epoch is ready. + // this mapping lets you go from the nodeAddressto the stakingAddress. + mapping(address => address) nodeAddressToStakerAddress; + // after the validator set is locked, nodes vote that they have successfully completed the PSS + // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance + mapping(address => bool) readyForNextEpoch; + // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they + // are removed from the next validator set + mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch)) votesToKickValidatorsInNextEpoch; + /// Maps kick reason to amount to slash + /// @notice Use complaintReasonToConfig instead. + mapping(uint256 => uint256) DEPRECATED_kickPenaltyPercentByReason; + // maps hash(comms_sender_pubkey,comms_receiver_pubkey) to a boolean to show if + // the set of comms keys has been used or not + mapping(bytes32 => bool) usedCommsKeys; + // This is the set of validators that are in the current validator set that are also kicked + // from the next validator set. + EnumerableSet.AddressSet currentValidatorsKickedFromNextEpoch; + // Mapping of the complaint reason code to the config for that reason + mapping(uint256 => ComplaintConfig) complaintReasonToConfig; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (StakingStorage storage storageStruct) + { + bytes32 position = STAKING_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/Staking/StakingFacet.sol b/contracts/lit-node/Staking/StakingFacet.sol new file mode 100644 index 0000000..2c24452 --- /dev/null +++ b/contracts/lit-node/Staking/StakingFacet.sol @@ -0,0 +1,779 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { StakingViewsFacet } from "./StakingViewsFacet.sol"; +import { StakingBalancesFacet } from "../StakingBalances/StakingBalancesFacet.sol"; + +import { LibStakingStorage } from "./LibStakingStorage.sol"; + +// import "hardhat/console.sol"; + +contract StakingFacet { + using EnumerableSet for EnumerableSet.AddressSet; + + // errors + error MustBeInActiveOrUnlockedState(LibStakingStorage.States state); + error MustBeInNextValidatorSetLockedOrReadyForNextEpochOrRestoreState( + LibStakingStorage.States state + ); + error MustBeInNextValidatorSetLockedState(LibStakingStorage.States state); + error MustBeInReadyForNextEpochState(LibStakingStorage.States state); + error MustBeInActiveOrUnlockedOrPausedState(LibStakingStorage.States state); + error MustBeInNextValidatorSetLockedOrReadyForNextEpochState( + LibStakingStorage.States state + ); + error NotEnoughValidatorsInNextEpoch( + uint256 validatorCount, + uint256 minimumValidatorCount + ); + error ValidatorIsNotInNextEpoch( + address validator, + address[] validatorsInNextEpoch + ); + error NotEnoughValidatorsReadyForNextEpoch( + uint256 currentReadyValidatorCount, + uint256 nextReadyValidatorCount, + uint256 minimumValidatorCountToBeReady + ); + error CannotKickBelowCurrentValidatorThreshold(); + error CannotStakeZero(); + error CannotRejoinUntilNextEpochBecauseKicked(address stakingAddress); + error ActiveValidatorsCannotLeave(); + error TryingToWithdrawMoreThanStaked( + uint256 yourBalance, + uint256 requestedWithdrawlAmount + ); + error CouldNotMapNodeAddressToStakerAddress(address nodeAddress); + error MustBeValidatorInNextEpochToKick(address stakerAddress); + error CannotVoteTwice(address stakerAddress); + error NotEnoughTimeElapsedSinceLastEpoch( + uint256 currentTimestamp, + uint256 epochEndTime + ); + error NotEnoughTimeElapsedForTimeoutSinceLastEpoch( + uint256 currentTimestamp, + uint256 epochEndTime, + uint256 timeout + ); + error CannotWithdrawZero(); + error CannotReuseCommsKeys(uint256 senderPubKey, uint256 receiverPubKey); + error StakerNotPermitted(address stakerAddress); + error SignaledReadyForWrongEpochNumber( + uint256 currentEpochNumber, + uint256 receivedEpochNumber + ); + error CallerNotOwner(); + + /* ========== Modifiers ========== */ + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + function s() + internal + pure + returns (LibStakingStorage.StakingStorage storage) + { + return LibStakingStorage.getStorage(); + } + + function views() internal view returns (StakingViewsFacet) { + return StakingViewsFacet(address(this)); + } + + function mutableEpoch() + internal + view + returns (LibStakingStorage.Epoch storage) + { + return s().epochs[0]; + } + + function mutableConfig() + internal + view + returns (LibStakingStorage.Config storage) + { + return s().configs[0]; + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /// Lock in the validators for the next epoch + function lockValidatorsForNextEpoch() external { + if (block.timestamp < mutableEpoch().endTime) { + revert NotEnoughTimeElapsedSinceLastEpoch( + block.timestamp, + mutableEpoch().endTime + ); + } + if ( + !(s().state == LibStakingStorage.States.Active || + s().state == LibStakingStorage.States.Unlocked) + ) { + revert MustBeInActiveOrUnlockedState(s().state); + } + if ( + s().validatorsInNextEpoch.length() < + mutableConfig().minimumValidatorCount + ) { + revert NotEnoughValidatorsInNextEpoch( + s().validatorsInNextEpoch.length(), + mutableConfig().minimumValidatorCount + ); + } + + s().state = LibStakingStorage.States.NextValidatorSetLocked; + emit StateChanged(s().state); + } + + /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress. + function signalReadyForNextEpoch(uint256 epochNumber) external { + if (mutableEpoch().number != epochNumber) { + revert SignaledReadyForWrongEpochNumber( + mutableEpoch().number, + epochNumber + ); + } + + address stakerAddress = s().nodeAddressToStakerAddress[msg.sender]; + if ( + !(s().state == LibStakingStorage.States.NextValidatorSetLocked || + s().state == LibStakingStorage.States.ReadyForNextEpoch || + s().state == LibStakingStorage.States.Restore) + ) { + revert MustBeInNextValidatorSetLockedOrReadyForNextEpochOrRestoreState( + s().state + ); + } + // at the first epoch, validatorsInCurrentEpoch is empty + if (mutableEpoch().number != 1) { + if (!s().validatorsInNextEpoch.contains(stakerAddress)) { + revert ValidatorIsNotInNextEpoch( + stakerAddress, + views().getValidatorsInNextEpoch() + ); + } + } + s().readyForNextEpoch[stakerAddress] = true; + emit ReadyForNextEpoch(stakerAddress, mutableEpoch().number); + + if (views().isReadyForNextEpoch()) { + s().state = LibStakingStorage.States.ReadyForNextEpoch; + emit StateChanged(s().state); + } + } + + /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers + function advanceEpoch() external { + if (block.timestamp < mutableEpoch().endTime) { + revert NotEnoughTimeElapsedSinceLastEpoch( + block.timestamp, + mutableEpoch().endTime + ); + } + if (s().state != LibStakingStorage.States.ReadyForNextEpoch) { + revert MustBeInReadyForNextEpochState(s().state); + } + if (!views().isReadyForNextEpoch()) { + revert NotEnoughValidatorsReadyForNextEpoch( + views().countOfCurrentValidatorsReadyForNextEpoch(), + views().countOfNextValidatorsReadyForNextEpoch(), + views().currentValidatorCountForConsensus() + ); + } + + // reward the validators + uint256 validatorLength = s().validatorsInCurrentEpoch.length(); + for (uint256 i = 0; i < validatorLength; i++) { + address validatorAddress = s().validatorsInCurrentEpoch.at(i); + IERC20Metadata stakingToken = IERC20Metadata( + views().getTokenAddress() + ); + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + uint256 reward = (mutableConfig().tokenRewardPerTokenPerEpoch * + stakingBalances.balanceOf(validatorAddress)) / + 10 ** stakingToken.decimals(); + stakingBalances.rewardValidator(reward, validatorAddress); + } + + // set the validators to the new validator set + // ideally we could just do this: + // validatorsInCurrentEpoch = validatorsInNextEpoch; + // but solidity doesn't allow that, so we have to do it manually + + // clear out validators in current epoch + clearEnumerableAddressSet(s().validatorsInCurrentEpoch); + + // copy validators from next epoch to current epoch + validatorLength = s().validatorsInNextEpoch.length(); + for (uint256 i = 0; i < validatorLength; i++) { + s().validatorsInCurrentEpoch.add(s().validatorsInNextEpoch.at(i)); + + // clear out readyForNextEpoch + s().readyForNextEpoch[s().validatorsInNextEpoch.at(i)] = false; + } + + // clear out the validators kicked from next epoch + clearEnumerableAddressSet(s().validatorsKickedFromNextEpoch); + + // clear out the current validators kicked from next epoch + clearEnumerableAddressSet(s().currentValidatorsKickedFromNextEpoch); + + mutableEpoch().number++; + mutableEpoch().endTime = block.timestamp + mutableEpoch().epochLength; + + s().state = LibStakingStorage.States.Active; + emit StateChanged(s().state); + } + + /// Stake and request to join the validator set + /// @param amount The amount of tokens to stake + /// @param ip The IP address of the node + /// @param port The port of the node + function stakeAndJoin( + uint256 amount, + uint32 ip, + uint128 ipv6, + uint32 port, + address nodeAddress, + uint256 senderPubKey, + uint256 receiverPubKey + ) external { + stake(amount); + requestToJoin( + ip, + ipv6, + port, + nodeAddress, + senderPubKey, + receiverPubKey + ); + } + + function stake(uint256 amount) public { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.stake(amount, msg.sender); + } + + function requestToJoin( + uint32 ip, + uint128 ipv6, + uint32 port, + address nodeAddress, + uint256 senderPubKey, + uint256 receiverPubKey + ) public { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.checkStakingAmounts(msg.sender); + + if ( + !(s().state == LibStakingStorage.States.Active || + s().state == LibStakingStorage.States.Unlocked || + s().state == LibStakingStorage.States.Paused) + ) { + revert MustBeInActiveOrUnlockedOrPausedState(s().state); + } + + // make sure they haven't been kicked + if (s().validatorsKickedFromNextEpoch.contains(msg.sender)) { + revert CannotRejoinUntilNextEpochBecauseKicked(msg.sender); + } + + bytes32 commsKeysHash = keccak256( + abi.encodePacked(senderPubKey, receiverPubKey) + ); + if (s().usedCommsKeys[commsKeysHash]) { + revert CannotReuseCommsKeys(senderPubKey, receiverPubKey); + } + s().usedCommsKeys[commsKeysHash] = true; + + if (stakingBalances.permittedStakersOn()) { + if (!stakingBalances.isPermittedStaker(msg.sender)) { + revert StakerNotPermitted(msg.sender); + } + } + + s().validators[msg.sender].ip = ip; + s().validators[msg.sender].ipv6 = ipv6; + s().validators[msg.sender].port = port; + s().validators[msg.sender].nodeAddress = nodeAddress; + s().validators[msg.sender].senderPubKey = senderPubKey; + s().validators[msg.sender].receiverPubKey = receiverPubKey; + s().nodeAddressToStakerAddress[nodeAddress] = msg.sender; + + s().validatorsInNextEpoch.add(msg.sender); + + emit RequestToJoin(msg.sender); + } + + /// Withdraw staked tokens. This can only be done by users who are not active in the validator set. + /// @param amount The amount of tokens to withdraw + function withdraw(uint256 amount) external { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.withdraw(amount, msg.sender); + } + + /// Request to leave in the next Epoch + function requestToLeave() external { + stakerRequestToLeave(msg.sender); + } + + function requestToLeaveAsNode() external { + address stakerAddress = s().nodeAddressToStakerAddress[msg.sender]; + if (stakerAddress == address(0)) { + revert CouldNotMapNodeAddressToStakerAddress(msg.sender); + } + stakerRequestToLeave(stakerAddress); + } + + function stakerRequestToLeave(address staker) internal { + if ( + !(s().state == LibStakingStorage.States.Active || + s().state == LibStakingStorage.States.Unlocked || + s().state == LibStakingStorage.States.Paused) + ) { + revert MustBeInActiveOrUnlockedOrPausedState(s().state); + } + if ( + s().validatorsInNextEpoch.length() - 1 < + mutableConfig().minimumValidatorCount + ) { + revert NotEnoughValidatorsInNextEpoch( + s().validatorsInNextEpoch.length(), + mutableConfig().minimumValidatorCount + ); + } + removeValidatorFromNextEpoch(staker); + emit RequestToLeave(staker); + } + + /// Transfer any outstanding reward tokens + function getReward() external { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.getReward(msg.sender); + } + + /// Exit staking and get any outstanding rewards + function exit() external { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.withdraw( + stakingBalances.balanceOf(msg.sender), + msg.sender + ); + stakingBalances.getReward(msg.sender); + } + + /// If more than the threshold of validators vote to kick someone, kick them. + /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress + function kickValidatorInNextEpoch( + address validatorStakerAddress, + uint256 reason, + bytes calldata data + ) external { + address stakerAddressOfSender = s().nodeAddressToStakerAddress[ + msg.sender + ]; + if (stakerAddressOfSender == address(0)) { + revert CouldNotMapNodeAddressToStakerAddress(msg.sender); + } + if (!s().validatorsInNextEpoch.contains(stakerAddressOfSender)) { + revert MustBeValidatorInNextEpochToKick(stakerAddressOfSender); + } + if ( + s() + .votesToKickValidatorsInNextEpoch[mutableEpoch().number][ + validatorStakerAddress + ].voted[stakerAddressOfSender] + ) { + revert CannotVoteTwice(stakerAddressOfSender); + } + + // A threshold number of validators from the current validator set MUST NOT + // be kicked in order for DKG resharing to be successful. + // This is only valid for epoch 2+ since epoch 1 has no current validator set, + // and if we enforce this in epoch 1, we are effectively prohibiting any votes + // to kick. + bool isValidatorInCurrentSet = s().validatorsInCurrentEpoch.contains( + validatorStakerAddress + ); + if ( + views().epoch().number > 1 && + s().currentValidatorsKickedFromNextEpoch.length() >= + (views().getValidatorsInCurrentEpoch().length - + views().currentValidatorCountForConsensus()) + ) { + revert CannotKickBelowCurrentValidatorThreshold(); + } + + // Vote to kick + s() + .votesToKickValidatorsInNextEpoch[mutableEpoch().number][ + validatorStakerAddress + ].votes++; + s() + .votesToKickValidatorsInNextEpoch[mutableEpoch().number][ + validatorStakerAddress + ].voted[stakerAddressOfSender] = true; + + if ( + s().validatorsInNextEpoch.contains(validatorStakerAddress) && + views().shouldKickValidator(validatorStakerAddress) + ) { + // remove them from the validator set + removeValidatorFromNextEpoch(validatorStakerAddress); + // block them from rejoining the next epoch + s().validatorsKickedFromNextEpoch.add(validatorStakerAddress); + // mark them if they are in the current validator set + if (isValidatorInCurrentSet) { + s().currentValidatorsKickedFromNextEpoch.add( + validatorStakerAddress + ); + } + + // slash the stake + uint256 kickPenaltyPercent = s() + .complaintReasonToConfig[reason] + .kickPenaltyPercent; + + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + uint256 amountToPenalize = (stakingBalances.balanceOf( + validatorStakerAddress + ) * kickPenaltyPercent) / 100; + + stakingBalances.penalizeTokens( + amountToPenalize, + validatorStakerAddress + ); + + // shame them with an event + emit ValidatorKickedFromNextEpoch( + validatorStakerAddress, + amountToPenalize + ); + + // if we're in the locked state, then we need to unlock, because we kicked a node + if ( + s().state == LibStakingStorage.States.NextValidatorSetLocked || + s().state == LibStakingStorage.States.ReadyForNextEpoch + ) { + unlockEpoch(); + } else if (s().state == LibStakingStorage.States.Active) { + // if we're in the active state, then we need to lock, because we kicked a node + // we want to kick off the next epoch transition to remove this node from the set + s().state = LibStakingStorage.States.NextValidatorSetLocked; + emit StateChanged(s().state); + // change the epoch end time to now + mutableEpoch().endTime = block.timestamp; + } + } + + emit VotedToKickValidatorInNextEpoch( + stakerAddressOfSender, + validatorStakerAddress, + reason, + data + ); + } + + function clearEnumerableAddressSet( + EnumerableSet.AddressSet storage set + ) internal { + while (set.length() > 0) { + set.remove(set.at(0)); + } + } + + /// Set the IP and port of your node + /// @param ip The ip address of your node + /// @param port The port of your node + function setIpPortNodeAddressAndCommunicationPubKeys( + uint32 ip, + uint128 ipv6, + uint32 port, + address nodeAddress, + uint256 senderPubKey, + uint256 receiverPubKey + ) external { + s().validators[msg.sender].ip = ip; + s().validators[msg.sender].ipv6 = ipv6; + s().validators[msg.sender].port = port; + s().validators[msg.sender].nodeAddress = nodeAddress; + s().validators[msg.sender].senderPubKey = senderPubKey; + s().validators[msg.sender].receiverPubKey = receiverPubKey; + + // don't let them overwrite an existing mapping + // becuase it could belong to someone else, + // but let them create a new mapping + if (s().nodeAddressToStakerAddress[nodeAddress] == address(0)) { + s().nodeAddressToStakerAddress[nodeAddress] = msg.sender; + } + } + + function setEpochLength(uint256 newEpochLength) external onlyOwner { + mutableEpoch().epochLength = newEpochLength; + emit EpochLengthSet(newEpochLength); + } + + function setEpochTimeout(uint256 newEpochTimeout) external onlyOwner { + mutableEpoch().timeout = newEpochTimeout; + emit EpochTimeoutSet(newEpochTimeout); + } + + function setEpochEndTime(uint256 newEpochEndTime) external onlyOwner { + mutableEpoch().endTime = newEpochEndTime; + emit EpochEndTimeSet(newEpochEndTime); + } + + function setContractResolver( + address newResolverAddress + ) external onlyOwner { + s().contractResolver = ContractResolver(newResolverAddress); + emit ResolverContractAddressSet(newResolverAddress); + } + + function setKickPenaltyPercent( + uint256 reason, + uint256 newKickPenaltyPercent + ) external onlyOwner { + s() + .complaintReasonToConfig[reason] + .kickPenaltyPercent = newKickPenaltyPercent; + emit KickPenaltyPercentSet(reason, newKickPenaltyPercent); + } + + function setEpochState( + LibStakingStorage.States newState + ) external onlyOwner { + s().state = newState; + emit StateChanged(newState); + } + + function adminKickValidatorInNextEpoch( + address validatorStakerAddress + ) external onlyOwner { + // block them from rejoining the next epoch + s().validatorsKickedFromNextEpoch.add(validatorStakerAddress); + + // remove from the validator set + removeValidatorFromNextEpoch(validatorStakerAddress); + + // if they're in the current set, we need to mark them as kicked from the current set too + bool isValidatorInCurrentSet = s().validatorsInCurrentEpoch.contains( + validatorStakerAddress + ); + if (isValidatorInCurrentSet) { + s().currentValidatorsKickedFromNextEpoch.add( + validatorStakerAddress + ); + } + emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0); + + // // if we're in the locked state, then we need to unlock, because we kicked a node + if ( + s().state == LibStakingStorage.States.NextValidatorSetLocked || + s().state == LibStakingStorage.States.ReadyForNextEpoch + ) { + unlockEpoch(); + } + } + + function adminSlashValidator( + address validatorStakerAddress, + uint256 amountToPenalize + ) external onlyOwner { + StakingBalancesFacet stakingBalances = StakingBalancesFacet( + views().getStakingBalancesAddress() + ); + stakingBalances.penalizeTokens( + amountToPenalize, + validatorStakerAddress + ); + } + + function removeValidatorFromNextEpoch(address staker) internal { + if (s().validatorsInNextEpoch.contains(staker)) { + // remove them + s().validatorsInNextEpoch.remove(staker); + } + LibStakingStorage.Validator memory validator = s().validators[staker]; + bytes32 commsKeysHash = keccak256( + abi.encodePacked(validator.senderPubKey, validator.receiverPubKey) + ); + s().usedCommsKeys[commsKeysHash] = false; + } + + function adminRejoinValidator(address staker) external onlyOwner { + if ( + !(s().state == LibStakingStorage.States.Active || + s().state == LibStakingStorage.States.Unlocked || + s().state == LibStakingStorage.States.Paused) + ) { + revert MustBeInActiveOrUnlockedOrPausedState(s().state); + } + + // remove from next validator kicked list + s().validatorsKickedFromNextEpoch.remove(staker); + // remove from current validator kicked list + s().currentValidatorsKickedFromNextEpoch.remove(staker); + // add to next validator set + s().validatorsInNextEpoch.add(staker); + emit ValidatorRejoinedNextEpoch(staker); + } + + function setConfig( + LibStakingStorage.Config memory newConfig + ) external onlyOwner { + require( + newConfig.minTripleCount <= newConfig.maxTripleCount, + "min triple count must be less than or equal to max triple count" + ); + + mutableConfig().tokenRewardPerTokenPerEpoch = newConfig + .tokenRewardPerTokenPerEpoch; + mutableConfig().keyTypes = newConfig.keyTypes; + mutableConfig().minimumValidatorCount = newConfig.minimumValidatorCount; + mutableConfig().maxConcurrentRequests = newConfig.maxConcurrentRequests; + mutableConfig().maxTripleCount = newConfig.maxTripleCount; + mutableConfig().minTripleCount = newConfig.minTripleCount; + mutableConfig().peerCheckingIntervalSecs = newConfig + .peerCheckingIntervalSecs; + mutableConfig().maxTripleConcurrency = newConfig.maxTripleConcurrency; + mutableConfig().rpcHealthcheckEnabled = newConfig.rpcHealthcheckEnabled; + + emit ConfigSet( + newConfig.tokenRewardPerTokenPerEpoch, + newConfig.keyTypes, + newConfig.minimumValidatorCount, + newConfig.maxConcurrentRequests, + newConfig.maxTripleCount, + newConfig.minTripleCount, + newConfig.peerCheckingIntervalSecs, + newConfig.maxTripleConcurrency, + newConfig.rpcHealthcheckEnabled + ); + } + + function setComplaintConfig( + uint256 reason, + LibStakingStorage.ComplaintConfig memory config + ) external onlyOwner { + s().complaintReasonToConfig[reason] = config; + } + + function adminResetEpoch() external onlyOwner { + require(s().env == ContractResolver.Env.Dev, "only for dev env"); + + // clear out validators in current epoch + clearEnumerableAddressSet(s().validatorsInCurrentEpoch); + + // clear out validators in next epoch + clearEnumerableAddressSet(s().validatorsInNextEpoch); + + // clear out the validators kicked from next epoch + clearEnumerableAddressSet(s().validatorsKickedFromNextEpoch); + + // clear out the current validators kicked from next epoch + clearEnumerableAddressSet(s().currentValidatorsKickedFromNextEpoch); + + // reset the epoch + mutableEpoch().number = 1; + mutableEpoch().endTime = block.timestamp + mutableEpoch().epochLength; + mutableEpoch().retries = 0; + + // reset the state + s().state = LibStakingStorage.States.Paused; + emit StateChanged(s().state); + } + + function unlockEpoch() internal { + // this should only be callable from the ReadyForNextEpoch state or the NextValidatorSetLocked state + if ( + !(s().state == LibStakingStorage.States.ReadyForNextEpoch || + s().state == LibStakingStorage.States.NextValidatorSetLocked) + ) { + revert MustBeInNextValidatorSetLockedOrReadyForNextEpochState( + s().state + ); + } + // clear out readyForNextEpoch for current nodes + uint256 validatorLength = s().validatorsInCurrentEpoch.length(); + for (uint256 i = 0; i < validatorLength; i++) { + s().readyForNextEpoch[s().validatorsInCurrentEpoch.at(i)] = false; + } + + // clear out readyForNextEpoch for next nodes + validatorLength = s().validatorsInNextEpoch.length(); + for (uint256 i = 0; i < validatorLength; i++) { + s().readyForNextEpoch[s().validatorsInNextEpoch.at(i)] = false; + } + + s().state = LibStakingStorage.States.Unlocked; + s().epochs[0].retries++; + emit StateChanged(s().state); + } + + /* ========== EVENTS ========== */ + + event RewardsDurationUpdated(uint256 newDuration); + event RequestToJoin(address indexed staker); + event RequestToLeave(address indexed staker); + event Recovered(address token, uint256 amount); + event ReadyForNextEpoch(address indexed staker, uint256 epochNumber); + event StateChanged(LibStakingStorage.States newState); + event VotedToKickValidatorInNextEpoch( + address indexed reporter, + address indexed validatorStakerAddress, + uint256 indexed reason, + bytes data + ); + event ValidatorKickedFromNextEpoch( + address indexed staker, + uint256 amountBurned + ); + + // onlyOwner events + event EpochLengthSet(uint256 newEpochLength); + event EpochTimeoutSet(uint256 newEpochTimeout); + event EpochEndTimeSet(uint256 newEpochEndTime); + event StakingTokenSet(address newStakingTokenAddress); + event KickPenaltyPercentSet(uint256 reason, uint256 newKickPenaltyPercent); + event ResolverContractAddressSet(address newResolverContractAddress); + event ConfigSet( + uint256 newTokenRewardPerTokenPerEpoch, + uint256[] newKeyTypes, + uint256 newMinimumValidatorCount, + uint256 newMaxConcurrentRequests, + uint256 newMaxTripleCount, + uint256 newMinTripleCount, + uint256 newPeerCheckingIntervalSecs, + uint256 newMaxTripleConcurrency, + bool newRpcHealthcheckEnabled + ); + event ComplaintConfigSet( + uint256 reason, + LibStakingStorage.ComplaintConfig config + ); + event ValidatorRejoinedNextEpoch(address staker); +} diff --git a/contracts/lit-node/Staking/StakingVersionFacet.sol b/contracts/lit-node/Staking/StakingVersionFacet.sol new file mode 100644 index 0000000..f3ce4fd --- /dev/null +++ b/contracts/lit-node/Staking/StakingVersionFacet.sol @@ -0,0 +1,129 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { StakingBalances } from "../StakingBalances.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +import { LibStakingStorage } from "./LibStakingStorage.sol"; + +// import "hardhat/console.sol"; + +contract StakingVersionFacet { + error CallerNotOwner(); + + /* ========== Modifiers ========== */ + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + + function getMinVersion() + external + view + returns (LibStakingStorage.Version memory) + { + return LibStakingStorage.getStorage().versionRequirements[0]; + } + + function getMaxVersion() + external + view + returns (LibStakingStorage.Version memory) + { + return LibStakingStorage.getStorage().versionRequirements[1]; + } + + function getMinVersionString() external view returns (string memory) { + LibStakingStorage.Version storage minVersion = LibStakingStorage + .getStorage() + .versionRequirements[0]; + + return + string( + abi.encodePacked( + Strings.toString(minVersion.major), + ".", + Strings.toString(minVersion.minor), + ".", + Strings.toString(minVersion.patch) + ) + ); + } + + function getMaxVersionString() external view returns (string memory) { + LibStakingStorage.Version storage maxVersion = LibStakingStorage + .getStorage() + .versionRequirements[1]; + + return + string( + abi.encodePacked( + Strings.toString(maxVersion.major), + ".", + Strings.toString(maxVersion.minor), + ".", + Strings.toString(maxVersion.patch) + ) + ); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + function setMinVersion( + LibStakingStorage.Version memory version + ) external onlyOwner { + LibStakingStorage.getStorage().versionRequirements[0] = version; + emit VersionRequirementsUpdated(0, version); + } + + function setMaxVersion( + LibStakingStorage.Version memory version + ) external onlyOwner { + LibStakingStorage.getStorage().versionRequirements[1] = version; + emit VersionRequirementsUpdated(1, version); + } + + function checkVersion( + LibStakingStorage.Version memory version + ) public view returns (bool) { + LibStakingStorage.Version storage minVersion = LibStakingStorage + .getStorage() + .versionRequirements[0]; + LibStakingStorage.Version storage maxVersion = LibStakingStorage + .getStorage() + .versionRequirements[1]; + + if ( + (version.major > minVersion.major && + version.major < maxVersion.major) || + (version.major == minVersion.major && + version.minor > minVersion.minor) || + (version.major == maxVersion.major && + version.minor < maxVersion.minor) || + (version.major == minVersion.major && + version.minor == minVersion.minor && + version.patch >= minVersion.patch) || + (version.major == maxVersion.major && + version.minor == maxVersion.minor && + version.patch <= maxVersion.patch) + ) { + return true; + } else { + return false; + } + } + + /* ========== EVENTS ========== */ + + event VersionRequirementsUpdated( + uint256 index, + LibStakingStorage.Version version + ); +} diff --git a/contracts/lit-node/Staking/StakingViewsFacet.sol b/contracts/lit-node/Staking/StakingViewsFacet.sol new file mode 100644 index 0000000..edbb218 --- /dev/null +++ b/contracts/lit-node/Staking/StakingViewsFacet.sol @@ -0,0 +1,307 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { StakingBalancesFacet } from "../StakingBalances/StakingBalancesFacet.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; + +import { LibStakingStorage } from "./LibStakingStorage.sol"; + +// import "hardhat/console.sol"; + +contract StakingViewsFacet { + using EnumerableSet for EnumerableSet.AddressSet; + + /* ========== VIEWS ========== */ + function stakingStorage() + internal + pure + returns (LibStakingStorage.StakingStorage storage) + { + return LibStakingStorage.getStorage(); + } + + function epoch() public view returns (LibStakingStorage.Epoch memory) { + return stakingStorage().epochs[0]; + } + + function config() public view returns (LibStakingStorage.Config memory) { + return stakingStorage().configs[0]; + } + + function complaintConfig( + uint256 reason + ) public view returns (LibStakingStorage.ComplaintConfig memory) { + return stakingStorage().complaintReasonToConfig[reason]; + } + + function getKeyTypes() external view returns (uint256[] memory) { + return config().keyTypes; + } + + function contractResolver() external view returns (address) { + return address(stakingStorage().contractResolver); + } + + function kickPenaltyPercentByReason( + uint256 reason + ) external view returns (uint256) { + return + stakingStorage().complaintReasonToConfig[reason].kickPenaltyPercent; + } + + function nodeAddressToStakerAddress( + address nodeAddress + ) external view returns (address) { + return stakingStorage().nodeAddressToStakerAddress[nodeAddress]; + } + + function readyForNextEpoch( + address stakerAddress + ) external view returns (bool) { + return stakingStorage().readyForNextEpoch[stakerAddress]; + } + + function state() external view returns (LibStakingStorage.States) { + return stakingStorage().state; + } + + /// get the token address from the resolver + function getTokenAddress() public view returns (address) { + return + stakingStorage().contractResolver.getContract( + stakingStorage().contractResolver.LIT_TOKEN_CONTRACT(), + stakingStorage().env + ); + } + + // get the staking balances address from the resolver + function getStakingBalancesAddress() public view returns (address) { + return + stakingStorage().contractResolver.getContract( + stakingStorage().contractResolver.STAKING_BALANCES_CONTRACT(), + stakingStorage().env + ); + } + + function validators( + address stakerAddress + ) public view returns (LibStakingStorage.Validator memory) { + return stakingStorage().validators[stakerAddress]; + } + + function isActiveValidator(address account) external view returns (bool) { + return stakingStorage().validatorsInCurrentEpoch.contains(account); + } + + function isActiveValidatorByNodeAddress( + address account + ) external view returns (bool) { + return + stakingStorage().validatorsInCurrentEpoch.contains( + stakingStorage().nodeAddressToStakerAddress[account] + ); + } + + function getVotingStatusToKickValidator( + uint256 epochNumber, + address validatorStakerAddress, + address voterStakerAddress + ) external view returns (uint256, bool) { + LibStakingStorage.VoteToKickValidatorInNextEpoch + storage votingStatus = stakingStorage() + .votesToKickValidatorsInNextEpoch[epochNumber][ + validatorStakerAddress + ]; + return (votingStatus.votes, votingStatus.voted[voterStakerAddress]); + } + + function getValidatorsInCurrentEpoch() + public + view + returns (address[] memory) + { + address[] memory values = new address[]( + stakingStorage().validatorsInCurrentEpoch.length() + ); + uint256 validatorLength = stakingStorage() + .validatorsInCurrentEpoch + .length(); + for (uint256 i = 0; i < validatorLength; i++) { + values[i] = stakingStorage().validatorsInCurrentEpoch.at(i); + } + return values; + } + + function getValidatorsInCurrentEpochLength() + external + view + returns (uint256) + { + return stakingStorage().validatorsInCurrentEpoch.length(); + } + + function getValidatorsInNextEpoch() public view returns (address[] memory) { + address[] memory values = new address[]( + stakingStorage().validatorsInNextEpoch.length() + ); + uint256 validatorLength = stakingStorage() + .validatorsInNextEpoch + .length(); + for (uint256 i = 0; i < validatorLength; i++) { + values[i] = stakingStorage().validatorsInNextEpoch.at(i); + } + return values; + } + + function getValidatorsStructs( + address[] memory addresses + ) public view returns (LibStakingStorage.Validator[] memory) { + LibStakingStorage.Validator[] + memory values = new LibStakingStorage.Validator[](addresses.length); + for (uint256 i = 0; i < addresses.length; i++) { + values[i] = stakingStorage().validators[addresses[i]]; + } + return values; + } + + function getValidatorsStructsInCurrentEpoch() + external + view + returns (LibStakingStorage.Validator[] memory) + { + address[] memory addresses = getValidatorsInCurrentEpoch(); + return getValidatorsStructs(addresses); + } + + function getValidatorsStructsInNextEpoch() + external + view + returns (LibStakingStorage.Validator[] memory) + { + address[] memory addresses = getValidatorsInNextEpoch(); + return getValidatorsStructs(addresses); + } + + function getNodeStakerAddressMappings( + address[] memory addresses + ) public view returns (LibStakingStorage.AddressMapping[] memory) { + LibStakingStorage.AddressMapping[] + memory values = new LibStakingStorage.AddressMapping[]( + addresses.length + ); + for (uint256 i = 0; i < addresses.length; i++) { + values[i].nodeAddress = addresses[i]; + values[i].stakerAddress = stakingStorage() + .nodeAddressToStakerAddress[addresses[i]]; + } + return values; + } + + function countOfCurrentValidatorsReadyForNextEpoch() + public + view + returns (uint256) + { + uint256 total = 0; + uint256 validatorLength = stakingStorage() + .validatorsInCurrentEpoch + .length(); + for (uint256 i = 0; i < validatorLength; i++) { + if ( + stakingStorage().readyForNextEpoch[ + stakingStorage().validatorsInCurrentEpoch.at(i) + ] + ) { + total++; + } + } + return total; + } + + function countOfNextValidatorsReadyForNextEpoch() + public + view + returns (uint256) + { + uint256 total = 0; + uint256 validatorLength = stakingStorage() + .validatorsInNextEpoch + .length(); + for (uint256 i = 0; i < validatorLength; i++) { + if ( + stakingStorage().readyForNextEpoch[ + stakingStorage().validatorsInNextEpoch.at(i) + ] + ) { + total++; + } + } + return total; + } + + function isReadyForNextEpoch() public view returns (bool) { + // confirm that current validator set is ready + if ( + countOfCurrentValidatorsReadyForNextEpoch() < + currentValidatorCountForConsensus() + ) { + return false; + } + + // confirm that next validator set is ready + if ( + countOfNextValidatorsReadyForNextEpoch() < + nextValidatorCountForConsensus() + ) { + return false; + } + + return true; + } + + function shouldKickValidator( + address stakerAddress + ) public view returns (bool) { + // 2/3 of validators must vote + // and we don't want to kick below the threshold + if ( + stakingStorage() + .votesToKickValidatorsInNextEpoch[epoch().number][stakerAddress] + .votes >= currentValidatorCountForConsensus() + ) { + return true; + } + return false; + } + + // currently set to 2/3. this could be changed to be configurable. + function currentValidatorCountForConsensus() public view returns (uint256) { + if (stakingStorage().validatorsInCurrentEpoch.length() == 2) { + return 1; + } + + return (stakingStorage().validatorsInCurrentEpoch.length() * 2) / 3; + } + + /// require all nodes in the next validator set to vote that they're ready + /// any offline nodes will be kicked from the next validator set so that's why this is safe + function nextValidatorCountForConsensus() public view returns (uint256) { + return stakingStorage().validatorsInNextEpoch.length(); + } + + function getKickedValidators() public view returns (address[] memory) { + address[] memory values = new address[]( + stakingStorage().validatorsKickedFromNextEpoch.length() + ); + uint256 validatorLength = stakingStorage() + .validatorsKickedFromNextEpoch + .length(); + for (uint256 i = 0; i < validatorLength; i++) { + values[i] = stakingStorage().validatorsKickedFromNextEpoch.at(i); + } + return values; + } +} diff --git a/contracts/lit-node/StakingBalances.sol b/contracts/lit-node/StakingBalances.sol new file mode 100644 index 0000000..bf3e025 --- /dev/null +++ b/contracts/lit-node/StakingBalances.sol @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +import { ContractResolver } from "../lit-core/ContractResolver.sol"; +import { LibStakingBalancesStorage } from "./StakingBalances/LibStakingBalancesStorage.sol"; + +// When no function exists for function called +error FunctionNotFound(bytes4 _functionSelector); + +// This is used in diamond constructor +// more arguments are added to this struct +// this avoids stack too deep errors +struct StakingArgs { + address owner; + address init; + bytes initCalldata; + address contractResolver; + ContractResolver.Env env; +} + +contract StakingBalances { + constructor( + IDiamondCut.FacetCut[] memory _diamondCut, + StakingArgs memory _args + ) payable { + LibDiamond.setContractOwner(_args.owner); + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); + + // Code can be added here to perform actions and set state variables. + LibStakingBalancesStorage + .getStorage() + .contractResolver = ContractResolver(_args.contractResolver); + LibStakingBalancesStorage.getStorage().env = _args.env; + + LibStakingBalancesStorage.getStorage().minimumStake = 1 * (10 ** 18); + LibStakingBalancesStorage + .getStorage() + .maximumStake = LibStakingBalancesStorage.getStorage().minimumStake; + LibStakingBalancesStorage.getStorage().maxAliasCount = 1; + } + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds + .facetAddressAndSelectorPosition[msg.sig] + .facetAddress; + if (facet == address(0)) { + revert FunctionNotFound(msg.sig); + } + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } +} diff --git a/contracts/lit-node/StakingBalances/LibStakingBalancesStorage.sol b/contracts/lit-node/StakingBalances/LibStakingBalancesStorage.sol new file mode 100644 index 0000000..5e249de --- /dev/null +++ b/contracts/lit-node/StakingBalances/LibStakingBalancesStorage.sol @@ -0,0 +1,50 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { BitMaps } from "@openzeppelin/contracts/utils/structs/BitMaps.sol"; +import "solidity-bytes-utils/contracts/BytesLib.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; + +library LibStakingBalancesStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + struct VoteToKickValidatorInNextEpoch { + uint256 votes; + mapping(address => bool) voted; + } + + bytes32 constant STAKING_BALANCES_POSITION = + keccak256("stakingbalances.storage"); + + struct StakingBalancesStorage { + ContractResolver contractResolver; + ContractResolver.Env env; + mapping(address => uint256) balances; + mapping(address => uint256) rewards; + // allowed stakers + mapping(address => bool) permittedStakers; + // maps alias address to real staker address + mapping(address => address) aliases; + // maps staker address to alias count + mapping(address => uint256) aliasCounts; + uint256 minimumStake; + uint256 maximumStake; + uint256 totalStaked; + bool permittedStakersOn; + uint256 maxAliasCount; + uint256 penaltyBalance; + } + + // Return ERC721 storage struct for reading and writing + function getStorage() + internal + pure + returns (StakingBalancesStorage storage storageStruct) + { + bytes32 position = STAKING_BALANCES_POSITION; + assembly { + storageStruct.slot := position + } + } +} diff --git a/contracts/lit-node/StakingBalances/StakingBalancesFacet.sol b/contracts/lit-node/StakingBalances/StakingBalancesFacet.sol new file mode 100644 index 0000000..0071ded --- /dev/null +++ b/contracts/lit-node/StakingBalances/StakingBalancesFacet.sol @@ -0,0 +1,389 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.17; + +import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { ContractResolver } from "../../lit-core/ContractResolver.sol"; +import { Staking } from "../Staking.sol"; +import { StakingFacet } from "../Staking/StakingFacet.sol"; +import { StakingViewsFacet } from "../Staking/StakingViewsFacet.sol"; +import { LibStakingBalancesStorage } from "./LibStakingBalancesStorage.sol"; +import { LibDiamond } from "../../libraries/LibDiamond.sol"; + +import "hardhat/console.sol"; + +contract StakingBalancesFacet { + using EnumerableSet for EnumerableSet.AddressSet; + + error CannotStakeZero(); + error StakeMustBeGreaterThanMinimumStake( + uint256 amountStaked, + uint256 minimumStake + ); + error StakeMustBeLessThanMaximumStake( + uint256 amountStaked, + uint256 maximumStake + ); + error TryingToWithdrawMoreThanStaked( + uint256 yourBalance, + uint256 requestedWithdrawlAmount + ); + error CannotWithdrawZero(); + error OnlyStakingContract(address sender); + error StakerNotPermitted(address stakerAddress); + error ActiveValidatorsCannotLeave(); + error MaxAliasCountReached(uint256 aliasCount); + error AliasNotOwnedBySender(address aliasAccount, address stakerAddress); + error CannotRemoveAliasOfActiveValidator(address aliasAccount); + error CallerNotOwner(); + + modifier onlyStakingContract() { + if (msg.sender != getStakingAddress()) { + revert OnlyStakingContract(msg.sender); + } + _; + } + + modifier onlyOwner() { + if (msg.sender != LibDiamond.contractOwner()) revert CallerNotOwner(); + _; + } + + /* ========== VIEWS ========== */ + function s() + internal + pure + returns (LibStakingBalancesStorage.StakingBalancesStorage storage) + { + return LibStakingBalancesStorage.getStorage(); + } + + function contractResolver() external view returns (address) { + return address(s().contractResolver); + } + + /// get the staking address from the resolver + function getStakingAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.STAKING_CONTRACT(), + s().env + ); + } + + /// get the token address from the resolver + function getTokenAddress() public view returns (address) { + return + s().contractResolver.getContract( + s().contractResolver.LIT_TOKEN_CONTRACT(), + s().env + ); + } + + function permittedStakersOn() public view returns (bool) { + return s().permittedStakersOn; + } + + function minimumStake() public view returns (uint256) { + return s().minimumStake; + } + + function maximumStake() public view returns (uint256) { + return s().maximumStake; + } + + function totalStaked() public view returns (uint256) { + return s().totalStaked; + } + + function balanceOf(address account) external view returns (uint256) { + // support aliases + if (s().aliases[account] != address(0)) { + account = s().aliases[account]; + } + return s().balances[account]; + } + + function rewardOf(address account) external view returns (uint256) { + // support aliases + if (s().aliases[account] != address(0)) { + account = s().aliases[account]; + } + return s().rewards[account]; + } + + function isPermittedStaker(address staker) public view returns (bool) { + // support aliases + if (s().aliases[staker] != address(0)) { + staker = s().aliases[staker]; + } + return s().permittedStakers[staker]; + } + + function checkStakingAmounts(address account) public view returns (bool) { + // support aliases + if (s().aliases[account] != address(0)) { + account = s().aliases[account]; + } + uint256 amountStaked = s().balances[account]; + if (amountStaked < s().minimumStake) { + revert StakeMustBeGreaterThanMinimumStake( + amountStaked, + s().minimumStake + ); + } + if (amountStaked > s().maximumStake) { + revert StakeMustBeLessThanMaximumStake( + amountStaked, + s().maximumStake + ); + } + return true; + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + /// Stake tokens for a validator + function stake(uint256 amount, address account) public onlyStakingContract { + if (amount == 0) { + revert CannotStakeZero(); + } + + if (s().permittedStakersOn && !s().permittedStakers[account]) { + revert StakerNotPermitted(account); + } + + ERC20Burnable stakingToken = ERC20Burnable(getTokenAddress()); + stakingToken.transferFrom(account, address(this), amount); + s().balances[account] += amount; + + s().totalStaked += amount; + + emit Staked(account, amount); + } + + /// Withdraw staked tokens. This can only be done by users who are not active in the validator set. + /// @param amount The amount of tokens to withdraw + function withdraw( + uint256 amount, + address account + ) public onlyStakingContract { + if (amount == 0) { + revert CannotWithdrawZero(); + } + StakingViewsFacet staking = StakingViewsFacet(getStakingAddress()); + address[] memory validatorsInCurrentEpoch = staking + .getValidatorsInCurrentEpoch(); + bool isValidatorInCurrentEpoch = false; + for (uint256 i = 0; i < validatorsInCurrentEpoch.length; i++) { + if (validatorsInCurrentEpoch[i] == account) { + isValidatorInCurrentEpoch = true; + break; + } + } + if (isValidatorInCurrentEpoch) { + revert ActiveValidatorsCannotLeave(); + } + + if (s().balances[account] < amount) { + revert TryingToWithdrawMoreThanStaked( + s().balances[account], + amount + ); + } + + s().totalStaked = s().totalStaked - amount; + s().balances[account] = s().balances[account] - amount; + + ERC20Burnable stakingToken = ERC20Burnable(getTokenAddress()); + stakingToken.transfer(account, amount); + emit Withdrawn(account, amount); + } + + function rewardValidator( + uint256 amount, + address account + ) public onlyStakingContract { + // support aliases + if (s().aliases[account] != address(0)) { + // only reward if the main staking account is not an active validator, too + StakingViewsFacet staking = StakingViewsFacet(getStakingAddress()); + if (staking.isActiveValidator(s().aliases[account])) { + emit ValidatorNotRewardedBecauseAlias( + s().aliases[account], + account + ); + return; + } + account = s().aliases[account]; + } + s().rewards[account] += amount; + emit ValidatorRewarded(account, amount); + } + + function penalizeTokens( + uint256 amount, + address account + ) public onlyStakingContract { + if (s().aliases[account] != address(0)) { + account = s().aliases[account]; + } + + s().balances[account] -= amount; + s().totalStaked -= amount; + + s().penaltyBalance += amount; + emit ValidatorTokensPenalized(account, amount); + } + + /// Transfer any outstanding reward tokens + function getReward(address account) public onlyStakingContract { + if (s().aliases[account] != address(0)) { + account = s().aliases[account]; + } + + uint256 reward = s().rewards[account]; + if (reward > 0) { + s().rewards[account] = 0; + ERC20Burnable stakingToken = ERC20Burnable(getStakingAddress()); + stakingToken.transfer(account, reward); + emit RewardPaid(account, reward); + } + } + + /// Add an alias. Must come from staker address. + function addAlias(address aliasAccount) public { + if (s().aliasCounts[msg.sender] >= s().maxAliasCount) { + revert MaxAliasCountReached(s().aliasCounts[msg.sender]); + } + s().aliases[aliasAccount] = msg.sender; + s().aliasCounts[msg.sender] += 1; + emit AliasAdded(msg.sender, aliasAccount); + } + + /// Remove an alias. Must come from staker address. + function removeAlias(address aliasAccount) public { + // auth + if (s().aliases[aliasAccount] != msg.sender) { + revert AliasNotOwnedBySender(aliasAccount, msg.sender); + } + // don't let them remove an alias of an active validator + StakingViewsFacet staking = StakingViewsFacet(getStakingAddress()); + if (staking.isActiveValidator(aliasAccount)) { + revert CannotRemoveAliasOfActiveValidator(aliasAccount); + } + + delete s().aliases[aliasAccount]; + s().aliasCounts[msg.sender] -= 1; + emit AliasRemoved(msg.sender, aliasAccount); + } + + function withdrawPenaltyTokens(uint256 balance) public onlyOwner { + require(balance <= s().penaltyBalance, "Not enough penalty balance"); + + s().penaltyBalance -= balance; + + ERC20Burnable stakingToken = ERC20Burnable(getTokenAddress()); + stakingToken.transfer(msg.sender, balance); + } + + function transferPenaltyTokens( + uint256 balance, + address recipient + ) public onlyOwner { + require(balance <= s().penaltyBalance, "Not enough penalty balance"); + + s().penaltyBalance -= balance; + + ERC20Burnable stakingToken = ERC20Burnable(getTokenAddress()); + stakingToken.transfer(recipient, balance); + } + + function restakePenaltyTokens( + address staker, + uint256 balance + ) public onlyOwner { + require(balance <= s().penaltyBalance, "Not enough penalty balance"); + + s().totalStaked += balance; + s().penaltyBalance -= balance; + + s().balances[staker] += balance; + + ERC20Burnable stakingToken = ERC20Burnable(getTokenAddress()); + stakingToken.transfer(address(this), balance); + } + + /// this is for if someone accidently sends unwrapped tokens + function withdraw() public onlyOwner { + uint256 withdrawAmount = address(this).balance; + (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(""); + require(sent); + } + + function addPermittedStakers(address[] memory stakers) public onlyOwner { + for (uint256 i = 0; i < stakers.length; i++) { + addPermittedStaker(stakers[i]); + } + } + + function addPermittedStaker(address staker) public onlyOwner { + s().permittedStakers[staker] = true; + emit PermittedStakerAdded(staker); + } + + function removePermittedStaker(address staker) public onlyOwner { + s().permittedStakers[staker] = false; + emit PermittedStakerRemoved(staker); + } + + function setPermittedStakersOn(bool permitted) public onlyOwner { + s().permittedStakersOn = permitted; + emit PermittedStakersOnChanged(permitted); + } + + function setMinimumStake(uint256 newMinimumStake) public onlyOwner { + s().minimumStake = newMinimumStake; + emit MinimumStakeSet(newMinimumStake); + } + + function setMaximumStake(uint256 newMaximumStake) public onlyOwner { + s().maximumStake = newMaximumStake; + emit MaximumStakeSet(newMaximumStake); + } + + function setContractResolver(address newResolverAddress) public onlyOwner { + s().contractResolver = ContractResolver(newResolverAddress); + emit ResolverContractAddressSet(newResolverAddress); + } + + function setMaxAliasCount(uint256 newMaxAliasCount) public onlyOwner { + s().maxAliasCount = newMaxAliasCount; + emit MaxAliasCountSet(newMaxAliasCount); + } + + /* ========== EVENTS ========== */ + + event Staked(address indexed staker, uint256 amount); + event Withdrawn(address indexed staker, uint256 amount); + event ValidatorRewarded(address indexed staker, uint256 amount); + event ValidatorTokensPenalized(address indexed staker, uint256 amount); + event RewardPaid(address indexed staker, uint256 reward); + event AliasAdded(address indexed staker, address aliasAccount); + event AliasRemoved(address indexed staker, address aliasAccount); + event ValidatorNotRewardedBecauseAlias( + address indexed staker, + address aliasAccount + ); + + // onlyOwner events + event TokenRewardPerTokenPerEpochSet( + uint256 newTokenRewardPerTokenPerEpoch + ); + event MinimumStakeSet(uint256 newMinimumStake); + event MaximumStakeSet(uint256 newMaximumStake); + event PermittedStakerAdded(address staker); + event PermittedStakerRemoved(address staker); + event PermittedStakersOnChanged(bool permittedStakersOn); + event ResolverContractAddressSet(address newResolverAddress); + event MaxAliasCountSet(uint newMaxAliasCount); +} diff --git a/contracts/WLIT.sol b/contracts/lit-node/WLIT.sol similarity index 100% rename from contracts/WLIT.sol rename to contracts/lit-node/WLIT.sol diff --git a/contracts/upgradeInitializers/DiamondInit.sol b/contracts/upgradeInitializers/DiamondInit.sol new file mode 100644 index 0000000..4b6b4f9 --- /dev/null +++ b/contracts/upgradeInitializers/DiamondInit.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol"; +import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; +import { IERC173 } from "../interfaces/IERC173.sol"; +import { IERC165 } from "../interfaces/IERC165.sol"; + +// It is expected that this contract is customized if you want to deploy your diamond +// with data from a deployment script. Use the init function to initialize state variables +// of your diamond. Add parameters to the init funciton if you need to. + +// Adding parameters to the `init` or other functions you add here can make a single deployed +// DiamondInit contract reusable accross upgrades, and can be used for multiple diamonds. + +contract DiamondInit { + // You can add parameters to this function in order to pass in + // data to set your own state variables + function init() external { + // adding ERC165 data + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + ds.supportedInterfaces[type(IERC165).interfaceId] = true; + ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true; + ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true; + ds.supportedInterfaces[type(IERC173).interfaceId] = true; + + // add your own state variables + // EIP-2535 specifies that the `diamondCut` function takes two optional + // arguments: address _init and bytes calldata _calldata + // These arguments are used to execute an arbitrary function using delegatecall + // in order to set state variables in the diamond during deployment or an upgrade + // More info here: https://eips.ethereum.org/EIPS/eip-2535#diamond-interface + } +} diff --git a/contracts/upgradeInitializers/DiamondMultiInit.sol b/contracts/upgradeInitializers/DiamondMultiInit.sol new file mode 100644 index 0000000..2c630d1 --- /dev/null +++ b/contracts/upgradeInitializers/DiamondMultiInit.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import { LibDiamond } from "../libraries/LibDiamond.sol"; + +error AddressAndCalldataLengthDoNotMatch( + uint256 _addressesLength, + uint256 _calldataLength +); + +contract DiamondMultiInit { + // This function is provided in the third parameter of the `diamondCut` function. + // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade. + + function multiInit( + address[] calldata _addresses, + bytes[] calldata _calldata + ) external { + if (_addresses.length != _calldata.length) { + revert AddressAndCalldataLengthDoNotMatch( + _addresses.length, + _calldata.length + ); + } + for (uint i; i < _addresses.length; i++) { + LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]); + } + } +} diff --git a/copy_contracts_from_monorepo.sh b/copy_contracts_from_monorepo.sh index 7084db2..77a62b2 100755 --- a/copy_contracts_from_monorepo.sh +++ b/copy_contracts_from_monorepo.sh @@ -1,3 +1,3 @@ #!/bin/bash -rsync -avr --progress --include="*/" --exclude="deployments" /Users/chris/Documents/WorkStuff/LIT/lit-assets/blockchain/contracts/lit-node/contracts ./ \ No newline at end of file +rsync -avr --progress --exclude='node_modules/' --exclude='wallets' --exclude='artifacts' --include='*/' --include='*' /Users/chris/Documents/WorkStuff/LIT/lit-assets/blockchain/contracts/ ./ \ No newline at end of file diff --git a/deployEverything.sh b/deployEverything.sh deleted file mode 100755 index 67cc75a..0000000 --- a/deployEverything.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -e -. "./deployInit.sh" - -echo "Deploy init completed" - -npx hardhat run --network "${NETWORK}" scripts/deploy_everything.js && npx hardhat run --network "${NETWORK}" scripts/fund_and_stake_nodes.js - - diff --git a/deployInit.sh b/deployInit.sh deleted file mode 100755 index 53b3b3a..0000000 --- a/deployInit.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -set -e - -export ENV="$1" -export RESOLVER_CONTRACT_ADDRESS="$2" -export NETWORK="$3" - -export SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -export LIT_OS_DIR="${SCRIPT_DIR}/../lit-os" - -setup_project() { - if [ ! -e "${LIT_OS_DIR}" ]; then - # checkout the lit-os repo - cd "${SCRIPT_DIR}/.." - git clone git@github.com:LIT-Protocol/lit-os.git - fi - - # Link the ContractResolver so we can call it. - if [ ! -e "${SCRIPT_DIR}/contracts/ContractResolver.sol" ]; then - ln -s "${LIT_OS_DIR}/blockchain/contracts/ContractResolver.sol" contracts/ - fi -} - -if [ -z "${ENV}" ]; then - echo "Usage: $0 " - exit 2 -fi -if [ "${ENV}" = "_SETUP_" ]; then - setup_project - exit 0 -fi -if [ "${ENV}" != "dev" ] && [ "${ENV}" != "staging" ] && [ "${ENV}" != "prod" ]; then - echo "Invalid environment (valid: dev, staging, prod)" - exit 2 -fi - -if [ -z "${NETWORK}" ]; then - NETWORK="mumbai" -fi - -if [ "${NETWORK}" == "localchain" ]; then - if [ "$(pidof anvil)" != "" ]; then - echo "Killing anvil..." - kill $(pidof anvil) - fi - - anvil & -fi - - -if [ -z "${RESOLVER_CONTRACT_ADDRESS}" ]; then - if [ -z "${LIT_RESOLVER_CONTRACT_ADDRESS}" ]; then - # deploy the resolver etc. - cd .. - cd lit-os/blockchain - ./scripts/deploy.sh "${ENV}" "${NETWORK}" - - export RESOLVER_CONTRACT_ADDRESS=$(cat deployed-contracts-$ENV.json | jq -r ".contractResolver") - cd ../.. - cd LitNodeContracts - - else - # Default from LIT_RESOLVER_CONTRACT_ADDRESS - export RESOLVER_CONTRACT_ADDRESS="${LIT_RESOLVER_CONTRACT_ADDRESS}" - fi -fi - -if [ -z "${LIT_SOLONET}" ]; then - export LIT_SOLONET="true" # default to solonet on right now -fi - - -if [ -n "${RESOLVER_CONTRACT_ADDRESS}" ]; then - setup_project -fi diff --git a/deployed-contracts-temp-localhost.json b/deployed-contracts-temp-localhost.json deleted file mode 100644 index 641b15b..0000000 --- a/deployed-contracts-temp-localhost.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "stakingContractAddress": "0x474663b167f0d179C5359160359BB18e925daef5", - "multisenderContractAddress": "0x92dfbDD149912f82be54Fd69b0320110b1F5A7fA", - "litTokenContractAddress": "0x18D290De0A4e1199dA226D6c1022eB1eDe3A9200", - "accessControlConditionsContractAddress": "0x6267eDCd7E8c68748A7c670Cd331649C9c8b1013", - "pkpNftContractAddress": "0xD716e915508EdB1dBf65A975872d78cc30578078", - "rateLimitNftContractAddress": "0x1Bc0bED99632B5f251fD17407e280E2c0400F3A5", - "pkpHelperContractAddress": "0x844eCBe4e72DEA1322804E0d6B7a4e4BE7aE2A96", - "pkpPermissionsContractAddress": "0x9fFc5094E312DA04FB00FB970bd65CBDe58A63A6", - "pkpNftMetadataContractAddress": "0xD604841Be5F975d6B85F383A973c31Dc4775f258", - "allowlistContractAddress": "0xd86f576A09A073ddb77871CC3631280990567a1c", - "resolverContractAddress": "0x976c34c57685594d631c731423aEC44059a09cC4", - "chainId": 80001, - "rpcUrl": "https://polygon-mumbai.g.alchemy.com/v2/onvoLvV97DDoLkAmdi0Cj7sxvfglKqDh", - "chainName": "mumbai", - "litNodeDomainName": "127.0.0.1", - "litNodePort": 7470, - "rocketPort": 7470 -} diff --git a/deployed-contracts-temp.json b/deployed-contracts-temp.json deleted file mode 100644 index 0032671..0000000 --- a/deployed-contracts-temp.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "stakingContractAddress": "0x2Be79261f706312F1F5855059f57Fd298F8e0646", - "multisenderContractAddress": "0x20E5fd54E5A8F6E77183D5270aEa0B093d93010e", - "litTokenContractAddress": "0x53695556f8a1a064EdFf91767f15652BbfaFaD04", - "accessControlConditionsContractAddress": "0x7226E7F20867C062daCf50a6d4f8dddE4d248812", - "pubkeyRouterContractAddress": "N/A", - "pkpNftContractAddress": "0x0B06059b15fFDE432C33a9379104Ea8DE2a9C2F8", - "rateLimitNftContractAddress": "0x393bf9aF30D0a28A98fF237184f7773474B0A1BF", - "pkpHelperContractAddress": "0x116532bD457c74f8de2d450cf62F0C6FF1C58CF4", - "pkpPermissionsContractAddress": "0x8b6F1c0C6C6a01f767E04DaC1C67bB76bF5DC9e4", - "pkpNftMetadataContractAddress": "0x47A3F03f38d7c059D6Aacf6c9f9A5279Ffda60fa", - "allowlistContractAddress": "0xa6D6c5098Ee0B239D73DF7113b7596D5322F26E0", - "resolverContractAddress": "0x7506DdFDEF7122a3686e4B2ed90ECDD0304076E8", - "chainId": 175177, - "rpcUrl": "https://lit-protocol.calderachain.xyz/http", - "chainName": "lit", - "litNodeDomainName": "127.0.0.1", - "litNodePort": 7470, - "rocketPort": 7470 -} \ No newline at end of file diff --git a/deployed_contracts_serrano.json b/deployed_contracts_serrano.json deleted file mode 100644 index f7310e4..0000000 --- a/deployed_contracts_serrano.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "stakingContractAddress": "0x433357a14c35815E6A32758fe95c93380D194aaf", - "multisenderContractAddress": "0x0EdD020f421adbB57D3efa5d2045a75E40385464", - "litTokenContractAddress": "0x53695556f8a1a064EdFf91767f15652BbfaFaD04", - "accessControlConditionsContractAddress": "0x8b353Bb9E26F2c2B8155f377982537C39AD01A1B", - "pubkeyRouterContractAddress": "0xB35cC6CaB1501d5F3b6b8fcF3215898C9d03E981", - "pkpNftContractAddress": "0x8F75a53F65e31DD0D2e40d0827becAaE2299D111", - "rateLimitNftContractAddress": "0x2D0f767eff47b44626832EcD2fda705eB9797c38", - "pkpHelperContractAddress": "0x8bB62077437D918891F12c7F35d9e1B78468bF11", - "pkpPermissionsContractAddress": "0x4Aed2F242E806c58758677059340e29E6B5b7619", - "pkpNftMetadataContractAddress": "0x4f7dBAfD2D9fF2bD4b2B00D470eCbe673e49c4D3", - "allowlistContractAddress": "0x81FB8e997E0908AD5792e6F8737245A1D78706E6", - "resolverContractAddress": "0xFCB3d8a54680e9337e3c8E60adC02F2aE8455A71", - "chainId": 175177, - "rpcUrl": "https://lit-protocol.calderachain.xyz/http", - "chainName": "lit", - "litNodeDomainName": "127.0.0.1", - "litNodePort": 7470, - "rocketPort": 7470 -} diff --git a/deployed_contracts_serrano_staging_mumbai.json b/deployed_contracts_serrano_staging_mumbai.json deleted file mode 100644 index 916365f..0000000 --- a/deployed_contracts_serrano_staging_mumbai.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "stakingContractAddress": "0xE4dF866c496dC9FB29B1Fc3B0a540590229603B7", - "multisenderContractAddress": "0x8C05B553Fd5EDf23e06DcA616E314CD59C9b76E5", - "litTokenContractAddress": "0x8f286a61728329AC8b2e5871aa336c2F24A51823", - "accessControlConditionsContractAddress": "0x39510f8C3a5A93D02F60bb7F8212e577Ff5729eD", - "pkpNftContractAddress": "0x685563445e8deB526CAB2AA89FAd324a9CA4aba4", - "rateLimitNftContractAddress": "0x0C8E129F033e615ac6D0d1b0209F6c06AcB4eEb7", - "pkpHelperContractAddress": "0x29b7Bc1f9F914DcFF247CB4DA1B67aF252a71D94", - "pkpPermissionsContractAddress": "0xC24A994b639F846B9c00204F95B13d7A1cF14712", - "pkpNftMetadataContractAddress": "0xd95752c016E18d0223739848Aeb15b6CBdcdf95F", - "allowlistContractAddress": "0xA34eD4aCdA7E0F1dccE3C8937271B43af7fa9D12", - "resolverContractAddress": "0xcb655e44439b3680B13a41a2f2E8e6C31cdf5A72", - "chainId": 80001, - "rpcUrl": "https://polygon-mumbai.g.alchemy.com/v2/onvoLvV97DDoLkAmdi0Cj7sxvfglKqDh", - "chainName": "mumbai", - "litNodeDomainName": "127.0.0.1", - "litNodePort": 7470, - "rocketPort": 7470 -} \ No newline at end of file diff --git a/deployments/lit_175177/AccessControlConditions.json b/deployments/lit_175177/AccessControlConditions.json deleted file mode 100644 index 4e1833d..0000000 --- a/deployments/lit_175177/AccessControlConditions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/AccessControlConditions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract AccessControlConditions is Ownable, ReentrancyGuard {\\n /* ========== STRUCTS ========== */\\n struct StoredCondition {\\n uint256 value;\\n uint256 securityHash;\\n uint256 chainId;\\n bool permanent;\\n address creator;\\n }\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(uint256 => StoredCondition) public storedConditions;\\n address public signer;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n signer = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function getCondition(uint256 key)\\n external\\n view\\n returns (StoredCondition memory)\\n {\\n return storedConditions[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent\\n ) external nonReentrant {\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n msg.sender\\n );\\n }\\n\\n function storeConditionWithSigner(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) external nonReentrant {\\n require(\\n msg.sender == signer,\\n \\\"Only signer can call storeConditionsWithSigner.\\\"\\n );\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n }\\n\\n function setSigner(address newSigner) public onlyOwner {\\n signer = newSigner;\\n }\\n\\n /* ========== PRIVATE FUNCTIONS ========== */\\n\\n function _storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) private {\\n require(key != 0, \\\"Key must not be zero\\\");\\n if (storedConditions[key].creator != address(0)) {\\n // this is an update\\n require(\\n storedConditions[key].creator == creatorAddress,\\n \\\"Only the condition creator can update it\\\"\\n );\\n require(\\n storedConditions[key].permanent == false,\\n \\\"This condition was stored with the Permanent flag and cannot be updated\\\"\\n );\\n require(msg.sender != signer, \\\"Signer cannot update conditions\\\");\\n }\\n storedConditions[key] = StoredCondition(\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n\\n emit ConditionStored(key, value, chainId, permanent, creatorAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ConditionStored(\\n uint256 indexed key,\\n uint256 value,\\n uint256 chainId,\\n bool permanent,\\n address creator\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x7226E7F20867C062daCf50a6d4f8dddE4d248812","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261007a60201b60201c565b61008260201b60201c565b6001808190555033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610146565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61128b806101556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"permanent","type":"bool"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"ConditionStored","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":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getCondition","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"internalType":"struct AccessControlConditions.StoredCondition","name":"","type":"tuple"}],"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":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"}],"name":"storeCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"storeConditionWithSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"storedConditions","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/Allowlist.json b/deployments/lit_175177/Allowlist.json deleted file mode 100644 index 3b2b0f2..0000000 --- a/deployments/lit_175177/Allowlist.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Allowlist.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Allowlist is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(bytes32 => bool) public allowedItems;\\n EnumerableSet.AddressSet admins;\\n bool public allowAll;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n admins.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function isAllowed(bytes32 key) external view returns (bool) {\\n if (allowAll) {\\n return true;\\n }\\n return allowedItems[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function setAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = true;\\n emit ItemAllowed(key);\\n }\\n\\n function setNotAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = false;\\n emit ItemNotAllowed(key);\\n }\\n\\n function addAdmin(address newAdmin) public onlyOwner {\\n admins.add(newAdmin);\\n emit AdminAdded(newAdmin);\\n }\\n\\n function removeAdmin(address newAdmin) public onlyOwner {\\n admins.remove(newAdmin);\\n emit AdminRemoved(newAdmin);\\n }\\n\\n function setAllowAll(bool _allowAll) public onlyOwner {\\n allowAll = _allowAll;\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ItemAllowed(bytes32 indexed key);\\n event ItemNotAllowed(bytes32 indexed key);\\n event AdminAdded(address indexed newAdmin);\\n event AdminRemoved(address indexed newAdmin);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xa6D6c5098Ee0B239D73DF7113b7596D5322F26E0","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261005260201b60201c565b61005a60201b60201c565b6001808190555061004c33600361011e60201b6105811790919060201c565b506101ed565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061014c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61015460201b60201c565b905092915050565b600061016683836101ca60201b60201c565b6101bf5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506101c4565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b610d2a806101fc6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063715018a611610071578063715018a614610150578063787552951461015a578063865815971461018a5780638767d9aa146101a65780638da5cb5b146101c2578063f2fde38b146101e0576100a9565b80631785f53c146100ae5780634d7d9c01146100ca5780634ee643a5146100e657806352f97536146101045780637048027514610134575b600080fd5b6100c860048036038101906100c39190610965565b6101fc565b005b6100e460048036038101906100df91906109ca565b61025f565b005b6100ee610284565b6040516100fb9190610a06565b60405180910390f35b61011e60048036038101906101199190610a57565b610297565b60405161012b9190610a06565b60405180910390f35b61014e60048036038101906101499190610965565b6102b7565b005b61015861031a565b005b610174600480360381019061016f9190610a57565b61032e565b6040516101819190610a06565b60405180910390f35b6101a4600480360381019061019f9190610a57565b610377565b005b6101c060048036038101906101bb9190610a57565b610426565b005b6101ca6104d5565b6040516101d79190610a93565b60405180910390f35b6101fa60048036038101906101f59190610965565b6104fe565b005b6102046105b1565b61021881600361062f90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b6102676105b1565b80600560006101000a81548160ff02191690831515021790555050565b600560009054906101000a900460ff1681565b60026020528060005260406000206000915054906101000a900460ff1681565b6102bf6105b1565b6102d381600361058190919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b6103226105b1565b61032c600061065f565b565b6000600560009054906101000a900460ff161561034e5760019050610372565b6002600083815260200190815260200160002060009054906101000a900460ff1690505b919050565b61038b33600361072390919063ffffffff16565b6103ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c190610b0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61043a33600361072390919063ffffffff16565b610479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047090610b0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6105066105b1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056c90610b9d565b60405180910390fd5b61057e8161065f565b50565b60006105a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610753565b905092915050565b6105b96107c3565b73ffffffffffffffffffffffffffffffffffffffff166105d76104d5565b73ffffffffffffffffffffffffffffffffffffffff161461062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062490610c09565b60405180910390fd5b565b6000610657836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6107cb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061074b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6108df565b905092915050565b600061075f83836108df565b6107b85782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506107bd565b600090505b92915050565b600033905090565b600080836001016000848152602001908152602001600020549050600081146108d35760006001826107fd9190610c62565b90506000600186600001805490506108159190610c62565b905081811461088457600086600001828154811061083657610835610c96565b5b906000526020600020015490508087600001848154811061085a57610859610c96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061089857610897610cc5565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108d9565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061093282610907565b9050919050565b61094281610927565b811461094d57600080fd5b50565b60008135905061095f81610939565b92915050565b60006020828403121561097b5761097a610902565b5b600061098984828501610950565b91505092915050565b60008115159050919050565b6109a781610992565b81146109b257600080fd5b50565b6000813590506109c48161099e565b92915050565b6000602082840312156109e0576109df610902565b5b60006109ee848285016109b5565b91505092915050565b610a0081610992565b82525050565b6000602082019050610a1b60008301846109f7565b92915050565b6000819050919050565b610a3481610a21565b8114610a3f57600080fd5b50565b600081359050610a5181610a2b565b92915050565b600060208284031215610a6d57610a6c610902565b5b6000610a7b84828501610a42565b91505092915050565b610a8d81610927565b82525050565b6000602082019050610aa86000830184610a84565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b6000610af5600c83610aae565b9150610b0082610abf565b602082019050919050565b60006020820190508181036000830152610b2481610ae8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b87602683610aae565b9150610b9282610b2b565b604082019050919050565b60006020820190508181036000830152610bb681610b7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610bf3602083610aae565b9150610bfe82610bbd565b602082019050919050565b60006020820190508181036000830152610c2281610be6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c6d82610c29565b9150610c7883610c29565b9250828203905081811115610c9057610c8f610c33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220377f48ac4fd34bdcab4c8d3151b9d1d4a1a79f588e27726a626ee78f179f9e4064736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063715018a611610071578063715018a614610150578063787552951461015a578063865815971461018a5780638767d9aa146101a65780638da5cb5b146101c2578063f2fde38b146101e0576100a9565b80631785f53c146100ae5780634d7d9c01146100ca5780634ee643a5146100e657806352f97536146101045780637048027514610134575b600080fd5b6100c860048036038101906100c39190610965565b6101fc565b005b6100e460048036038101906100df91906109ca565b61025f565b005b6100ee610284565b6040516100fb9190610a06565b60405180910390f35b61011e60048036038101906101199190610a57565b610297565b60405161012b9190610a06565b60405180910390f35b61014e60048036038101906101499190610965565b6102b7565b005b61015861031a565b005b610174600480360381019061016f9190610a57565b61032e565b6040516101819190610a06565b60405180910390f35b6101a4600480360381019061019f9190610a57565b610377565b005b6101c060048036038101906101bb9190610a57565b610426565b005b6101ca6104d5565b6040516101d79190610a93565b60405180910390f35b6101fa60048036038101906101f59190610965565b6104fe565b005b6102046105b1565b61021881600361062f90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b6102676105b1565b80600560006101000a81548160ff02191690831515021790555050565b600560009054906101000a900460ff1681565b60026020528060005260406000206000915054906101000a900460ff1681565b6102bf6105b1565b6102d381600361058190919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b6103226105b1565b61032c600061065f565b565b6000600560009054906101000a900460ff161561034e5760019050610372565b6002600083815260200190815260200160002060009054906101000a900460ff1690505b919050565b61038b33600361072390919063ffffffff16565b6103ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c190610b0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61043a33600361072390919063ffffffff16565b610479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047090610b0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6105066105b1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056c90610b9d565b60405180910390fd5b61057e8161065f565b50565b60006105a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610753565b905092915050565b6105b96107c3565b73ffffffffffffffffffffffffffffffffffffffff166105d76104d5565b73ffffffffffffffffffffffffffffffffffffffff161461062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062490610c09565b60405180910390fd5b565b6000610657836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6107cb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061074b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6108df565b905092915050565b600061075f83836108df565b6107b85782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506107bd565b600090505b92915050565b600033905090565b600080836001016000848152602001908152602001600020549050600081146108d35760006001826107fd9190610c62565b90506000600186600001805490506108159190610c62565b905081811461088457600086600001828154811061083657610835610c96565b5b906000526020600020015490508087600001848154811061085a57610859610c96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061089857610897610cc5565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108d9565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061093282610907565b9050919050565b61094281610927565b811461094d57600080fd5b50565b60008135905061095f81610939565b92915050565b60006020828403121561097b5761097a610902565b5b600061098984828501610950565b91505092915050565b60008115159050919050565b6109a781610992565b81146109b257600080fd5b50565b6000813590506109c48161099e565b92915050565b6000602082840312156109e0576109df610902565b5b60006109ee848285016109b5565b91505092915050565b610a0081610992565b82525050565b6000602082019050610a1b60008301846109f7565b92915050565b6000819050919050565b610a3481610a21565b8114610a3f57600080fd5b50565b600081359050610a5181610a2b565b92915050565b600060208284031215610a6d57610a6c610902565b5b6000610a7b84828501610a42565b91505092915050565b610a8d81610927565b82525050565b6000602082019050610aa86000830184610a84565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b6000610af5600c83610aae565b9150610b0082610abf565b602082019050919050565b60006020820190508181036000830152610b2481610ae8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b87602683610aae565b9150610b9282610b2b565b604082019050919050565b60006020820190508181036000830152610bb681610b7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610bf3602083610aae565b9150610bfe82610bbd565b602082019050919050565b60006020820190508181036000830152610c2281610be6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c6d82610c29565b9150610c7883610c29565b9250828203905081811115610c9057610c8f610c33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220377f48ac4fd34bdcab4c8d3151b9d1d4a1a79f588e27726a626ee78f179f9e4064736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemNotAllowed","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":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"allowedItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_allowAll","type":"bool"}],"name":"setAllowAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/Multisender.json b/deployments/lit_175177/Multisender.json deleted file mode 100644 index 667ed0e..0000000 --- a/deployments/lit_175177/Multisender.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Multisender.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// This contract does one thing, simply. it allows you to send eth or tokens to multiple recipients. Useful for setting up a testnet and funding all the validators and stakers.\\n\\ncontract Multisender is Ownable {\\n function sendEth(address[] calldata _recipients) public payable {\\n uint256 val = msg.value / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n payable(_recipients[i]).transfer(val);\\n }\\n }\\n\\n function sendTokens(address[] calldata _recipients, address tokenContract)\\n public\\n {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n uint256 val = bal / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n tkn.transfer(_recipients[i], val);\\n }\\n }\\n\\n function withdraw() public onlyOwner {\\n payable(msg.sender).transfer(address(this).balance);\\n }\\n\\n function withdrawTokens(address tokenContract) public onlyOwner {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n tkn.transfer(msg.sender, bal);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x20E5fd54E5A8F6E77183D5270aEa0B093d93010e","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610bf98061010d6000396000f3fe6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","abi":[{"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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"sendEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"address","name":"tokenContract","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/PKPHelper.json b/deployments/lit_175177/PKPHelper.json deleted file mode 100644 index 247f9d9..0000000 --- a/deployments/lit_175177/PKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = PKPNFT(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNextAndAddAuthMethods(\\n uint256 keyType,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintNextAndAddAuthMethodsWithTypes(\\n keyType,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintNextAndAddAuthMethodsWithTypes(\\n uint256 keyType,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mintNext{ value: msg.value }(keyType);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpPermissions.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x292Bd736520B90C6fFeDE5009B8b1A5C40177569","bytecode":"0x60806040523480156200001157600080fd5b50604051620024f3380380620024f3833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b612285806200026e6000396000f3fe6080604052600436106100915760003560e01c80638da5cb5b116100595780638da5cb5b1461016c57806397016f3f146101975780639fba176b146101c2578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc5780631f71cb3114610125578063715018a614610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117c0565b60405180910390f35b34801561016157600080fd5b5061016a610b59565b005b34801561017857600080fd5b50610181610b6d565b60405161018e91906117ea565b60405180910390f35b3480156101a357600080fd5b506101ac610b96565b6040516101b99190611864565b60405180910390f35b6101dc60048036038101906101d7919061187f565b610bbc565b6040516101e991906117c0565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119b2565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a50565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d228b16348f6040518363ffffffff1660e01b81526004016103e291906117c0565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611a85565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611b24565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611bb6565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611c48565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611cda565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611d6c565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611d8c565b5b60200260200101518f85815181106105fd576105fc611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611ef8565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611f6c565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611d8c565b5b60200260200101518d85815181106106ec576106eb611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161071293929190611fb4565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611f6c565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611d8c565b5b602002602001015181526020018c86815181106107eb576107ea611d8c565b5b602002602001015181526020018b868151811061080b5761080a611d8c565b5b602002602001015181525089858151811061082957610828611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161084f93929190612093565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611f6c565b915050610765565b505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117c0565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093491906120ed565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff8111156109975761099661112d565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e493929190611fb4565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c9392919061211a565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b129392919061211a565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b610b61610dba565b610b6b6000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610d0488600067ffffffffffffffff811115610bdd57610bdc61112d565b5b604051908082528060200260200182016040528015610c1057816020015b6060815260200190600190039081610bfb5790505b50600067ffffffffffffffff811115610c2c57610c2b61112d565b5b604051908082528060200260200182016040528015610c5f57816020015b6060815260200190600190039081610c4a5790505b50600067ffffffffffffffff811115610c7b57610c7a61112d565b5b604051908082528060200260200182016040528015610ca95781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610cc557610cc461112d565b5b604051908082528060200260200182016040528015610cf857816020015b6060815260200190600190039081610ce35790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f906121c3565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610b6d565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d9061222f565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111658261111c565b810181811067ffffffffffffffff821117156111845761118361112d565b5b80604052505050565b6000611197610f04565b90506111a3828261115c565b919050565b600067ffffffffffffffff8211156111c3576111c261112d565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff8211156111f4576111f361112d565b5b6111fd8261111c565b9050602081019050919050565b82818337600083830152505050565b600061122c611227846111d9565b61118d565b905082815260208101848484011115611248576112476111d4565b5b61125384828561120a565b509392505050565b600082601f8301126112705761126f610fac565b5b8135611280848260208601611219565b91505092915050565b600061129c611297846111a8565b61118d565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261125b565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff8211156113595761135861112d565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156113855761138461112d565b5b602082029050602081019050919050565b60006113a96113a48461136a565b61118d565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b61118d565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc61112d565b5b602082029050602081019050919050565b600061152161151c846114e2565b61118d565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60006116118e828f01610f97565b9b505060208c013567ffffffffffffffff81111561163257611631610f13565b5b61163e8e828f01611310565b9a505060408c013567ffffffffffffffff81111561165f5761165e610f13565b5b61166b8e828f016114b4565b99505060608c013567ffffffffffffffff81111561168c5761168b610f13565b5b6116988e828f01611577565b98505060808c013567ffffffffffffffff8111156116b9576116b8610f13565b5b6116c58e828f016114b4565b97505060a08c013567ffffffffffffffff8111156116e6576116e5610f13565b5b6116f28e828f016113ff565b96505060c08c013567ffffffffffffffff81111561171357611712610f13565b5b61171f8e828f01611310565b95505060e08c013567ffffffffffffffff8111156117405761173f610f13565b5b61174c8e828f01611310565b9450506101008c013567ffffffffffffffff81111561176e5761176d610f13565b5b61177a8e828f016114b4565b93505061012061178c8e828f016115c8565b92505061014061179e8e828f016115c8565b9150509295989b509295989b9093969950565b6117ba81610f76565b82525050565b60006020820190506117d560008301846117b1565b92915050565b6117e481610f38565b82525050565b60006020820190506117ff60008301846117db565b92915050565b6000819050919050565b600061182a61182561182084610f18565b611805565b610f18565b9050919050565b600061183c8261180f565b9050919050565b600061184e82611831565b9050919050565b61185e81611843565b82525050565b60006020820190506118796000830184611855565b92915050565b600080600080600080600060e0888a03121561189e5761189d610f0e565b5b60006118ac8a828b01610f97565b975050602088013567ffffffffffffffff8111156118cd576118cc610f13565b5b6118d98a828b016113ff565b965050604088013567ffffffffffffffff8111156118fa576118f9610f13565b5b6119068a828b01611310565b955050606088013567ffffffffffffffff81111561192757611926610f13565b5b6119338a828b01611310565b945050608088013567ffffffffffffffff81111561195457611953610f13565b5b6119608a828b016114b4565b93505060a06119718a828b016115c8565b92505060c06119828a828b016115c8565b91505092959891949750929550565b600061199c82611831565b9050919050565b6119ac81611991565b82525050565b60006020820190506119c760008301846119a3565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a3a603a836119cd565b9150611a45826119de565b604082019050919050565b60006020820190508181036000830152611a6981611a2d565b9050919050565b600081519050611a7f81610f80565b92915050565b600060208284031215611a9b57611a9a610f0e565b5b6000611aa984828501611a70565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611b0e6036836119cd565b9150611b1982611ab2565b604082019050919050565b60006020820190508181036000830152611b3d81611b01565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611ba06035836119cd565b9150611bab82611b44565b604082019050919050565b60006020820190508181036000830152611bcf81611b93565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611c32603b836119cd565b9150611c3d82611bd6565b604082019050919050565b60006020820190508181036000830152611c6181611c25565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611cc4603f836119cd565b9150611ccf82611c68565b604082019050919050565b60006020820190508181036000830152611cf381611cb7565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d56603f836119cd565b9150611d6182611cfa565b604082019050919050565b60006020820190508181036000830152611d8581611d49565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60005b83811015611df5578082015181840152602081019050611dda565b60008484015250505050565b6000611e0c82611dbb565b611e168185611dc6565b9350611e26818560208601611dd7565b611e2f8161111c565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611e6f81610f76565b82525050565b6000611e818383611e66565b60208301905092915050565b6000602082019050919050565b6000611ea582611e3a565b611eaf8185611e45565b9350611eba83611e56565b8060005b83811015611eeb578151611ed28882611e75565b9750611edd83611e8d565b925050600181019050611ebe565b5085935050505092915050565b6000606082019050611f0d60008301866117b1565b8181036020830152611f1f8185611e01565b90508181036040830152611f338184611e9a565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f7782610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fa957611fa8611f3d565b5b600182019050919050565b6000606082019050611fc960008301866117b1565b611fd660208301856117db565b8181036040830152611fe88184611e9a565b9050949350505050565b600082825260208201905092915050565b600061200e82611dbb565b6120188185611ff2565b9350612028818560208601611dd7565b6120318161111c565b840191505092915050565b60006060830160008301516120546000860182611e66565b506020830151848203602086015261206c8282612003565b915050604083015184820360408601526120868282612003565b9150508091505092915050565b60006060820190506120a860008301866117b1565b81810360208301526120ba818561203c565b905081810360408301526120ce8184611e9a565b9050949350505050565b6000815190506120e781610f4a565b92915050565b60006020828403121561210357612102610f0e565b5b6000612111848285016120d8565b91505092915050565b600060608201905061212f60008301866117db565b61213c60208301856117db565b61214960408301846117b1565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006121ad6026836119cd565b91506121b882612151565b604082019050919050565b600060208201905081810360008301526121dc816121a0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122196020836119cd565b9150612224826121e3565b602082019050919050565b600060208201905081810360008301526122488161220c565b905091905056fea26469706673582212203d178313eafbfaed07329298f28b350442e4de026cd6738b76081eacf3ac818864736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c80638da5cb5b116100595780638da5cb5b1461016c57806397016f3f146101975780639fba176b146101c2578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc5780631f71cb3114610125578063715018a614610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117c0565b60405180910390f35b34801561016157600080fd5b5061016a610b59565b005b34801561017857600080fd5b50610181610b6d565b60405161018e91906117ea565b60405180910390f35b3480156101a357600080fd5b506101ac610b96565b6040516101b99190611864565b60405180910390f35b6101dc60048036038101906101d7919061187f565b610bbc565b6040516101e991906117c0565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119b2565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a50565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d228b16348f6040518363ffffffff1660e01b81526004016103e291906117c0565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611a85565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611b24565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611bb6565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611c48565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611cda565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611d6c565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611d8c565b5b60200260200101518f85815181106105fd576105fc611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611ef8565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611f6c565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611d8c565b5b60200260200101518d85815181106106ec576106eb611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161071293929190611fb4565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611f6c565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611d8c565b5b602002602001015181526020018c86815181106107eb576107ea611d8c565b5b602002602001015181526020018b868151811061080b5761080a611d8c565b5b602002602001015181525089858151811061082957610828611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161084f93929190612093565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611f6c565b915050610765565b505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117c0565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093491906120ed565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff8111156109975761099661112d565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e493929190611fb4565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c9392919061211a565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b129392919061211a565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b610b61610dba565b610b6b6000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610d0488600067ffffffffffffffff811115610bdd57610bdc61112d565b5b604051908082528060200260200182016040528015610c1057816020015b6060815260200190600190039081610bfb5790505b50600067ffffffffffffffff811115610c2c57610c2b61112d565b5b604051908082528060200260200182016040528015610c5f57816020015b6060815260200190600190039081610c4a5790505b50600067ffffffffffffffff811115610c7b57610c7a61112d565b5b604051908082528060200260200182016040528015610ca95781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610cc557610cc461112d565b5b604051908082528060200260200182016040528015610cf857816020015b6060815260200190600190039081610ce35790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f906121c3565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610b6d565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d9061222f565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111658261111c565b810181811067ffffffffffffffff821117156111845761118361112d565b5b80604052505050565b6000611197610f04565b90506111a3828261115c565b919050565b600067ffffffffffffffff8211156111c3576111c261112d565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff8211156111f4576111f361112d565b5b6111fd8261111c565b9050602081019050919050565b82818337600083830152505050565b600061122c611227846111d9565b61118d565b905082815260208101848484011115611248576112476111d4565b5b61125384828561120a565b509392505050565b600082601f8301126112705761126f610fac565b5b8135611280848260208601611219565b91505092915050565b600061129c611297846111a8565b61118d565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261125b565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff8211156113595761135861112d565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156113855761138461112d565b5b602082029050602081019050919050565b60006113a96113a48461136a565b61118d565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b61118d565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc61112d565b5b602082029050602081019050919050565b600061152161151c846114e2565b61118d565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60006116118e828f01610f97565b9b505060208c013567ffffffffffffffff81111561163257611631610f13565b5b61163e8e828f01611310565b9a505060408c013567ffffffffffffffff81111561165f5761165e610f13565b5b61166b8e828f016114b4565b99505060608c013567ffffffffffffffff81111561168c5761168b610f13565b5b6116988e828f01611577565b98505060808c013567ffffffffffffffff8111156116b9576116b8610f13565b5b6116c58e828f016114b4565b97505060a08c013567ffffffffffffffff8111156116e6576116e5610f13565b5b6116f28e828f016113ff565b96505060c08c013567ffffffffffffffff81111561171357611712610f13565b5b61171f8e828f01611310565b95505060e08c013567ffffffffffffffff8111156117405761173f610f13565b5b61174c8e828f01611310565b9450506101008c013567ffffffffffffffff81111561176e5761176d610f13565b5b61177a8e828f016114b4565b93505061012061178c8e828f016115c8565b92505061014061179e8e828f016115c8565b9150509295989b509295989b9093969950565b6117ba81610f76565b82525050565b60006020820190506117d560008301846117b1565b92915050565b6117e481610f38565b82525050565b60006020820190506117ff60008301846117db565b92915050565b6000819050919050565b600061182a61182561182084610f18565b611805565b610f18565b9050919050565b600061183c8261180f565b9050919050565b600061184e82611831565b9050919050565b61185e81611843565b82525050565b60006020820190506118796000830184611855565b92915050565b600080600080600080600060e0888a03121561189e5761189d610f0e565b5b60006118ac8a828b01610f97565b975050602088013567ffffffffffffffff8111156118cd576118cc610f13565b5b6118d98a828b016113ff565b965050604088013567ffffffffffffffff8111156118fa576118f9610f13565b5b6119068a828b01611310565b955050606088013567ffffffffffffffff81111561192757611926610f13565b5b6119338a828b01611310565b945050608088013567ffffffffffffffff81111561195457611953610f13565b5b6119608a828b016114b4565b93505060a06119718a828b016115c8565b92505060c06119828a828b016115c8565b91505092959891949750929550565b600061199c82611831565b9050919050565b6119ac81611991565b82525050565b60006020820190506119c760008301846119a3565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a3a603a836119cd565b9150611a45826119de565b604082019050919050565b60006020820190508181036000830152611a6981611a2d565b9050919050565b600081519050611a7f81610f80565b92915050565b600060208284031215611a9b57611a9a610f0e565b5b6000611aa984828501611a70565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611b0e6036836119cd565b9150611b1982611ab2565b604082019050919050565b60006020820190508181036000830152611b3d81611b01565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611ba06035836119cd565b9150611bab82611b44565b604082019050919050565b60006020820190508181036000830152611bcf81611b93565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611c32603b836119cd565b9150611c3d82611bd6565b604082019050919050565b60006020820190508181036000830152611c6181611c25565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611cc4603f836119cd565b9150611ccf82611c68565b604082019050919050565b60006020820190508181036000830152611cf381611cb7565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d56603f836119cd565b9150611d6182611cfa565b604082019050919050565b60006020820190508181036000830152611d8581611d49565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60005b83811015611df5578082015181840152602081019050611dda565b60008484015250505050565b6000611e0c82611dbb565b611e168185611dc6565b9350611e26818560208601611dd7565b611e2f8161111c565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611e6f81610f76565b82525050565b6000611e818383611e66565b60208301905092915050565b6000602082019050919050565b6000611ea582611e3a565b611eaf8185611e45565b9350611eba83611e56565b8060005b83811015611eeb578151611ed28882611e75565b9750611edd83611e8d565b925050600181019050611ebe565b5085935050505092915050565b6000606082019050611f0d60008301866117b1565b8181036020830152611f1f8185611e01565b90508181036040830152611f338184611e9a565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f7782610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fa957611fa8611f3d565b5b600182019050919050565b6000606082019050611fc960008301866117b1565b611fd660208301856117db565b8181036040830152611fe88184611e9a565b9050949350505050565b600082825260208201905092915050565b600061200e82611dbb565b6120188185611ff2565b9350612028818560208601611dd7565b6120318161111c565b840191505092915050565b60006060830160008301516120546000860182611e66565b506020830151848203602086015261206c8282612003565b915050604083015184820360408601526120868282612003565b9150508091505092915050565b60006060820190506120a860008301866117b1565b81810360208301526120ba818561203c565b905081810360408301526120ce8184611e9a565b9050949350505050565b6000815190506120e781610f4a565b92915050565b60006020828403121561210357612102610f0e565b5b6000612111848285016120d8565b91505092915050565b600060608201905061212f60008301866117db565b61213c60208301856117db565b61214960408301846117b1565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006121ad6026836119cd565b91506121b882612151565b604082019050919050565b600060208201905081810360008301526121dc816121a0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122196020836119cd565b9150612224826121e3565b602082019050919050565b600060208201905081810360008301526122488161220c565b905091905056fea26469706673582212203d178313eafbfaed07329298f28b350442e4de026cd6738b76081eacf3ac818864736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintNextAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintNextAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/PKPNFT.json b/deployments/lit_175177/PKPNFT.json deleted file mode 100644 index dd302ea..0000000 --- a/deployments/lit_175177/PKPNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xC71d07cDf7f577958445aA2911964d97305135f9","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000463565b508060019081620000a1919062000463565b505050620000c4620000b86200011b60201b60201c565b6200012360201b60201c565b6001600b819055506001600f8190555033601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200054a565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200026b57607f821691505b60208210810362000281576200028062000223565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002ac565b620002f78683620002ac565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003446200033e62000338846200030f565b62000319565b6200030f565b9050919050565b6000819050919050565b620003608362000323565b620003786200036f826200034b565b848454620002b9565b825550505050565b600090565b6200038f62000380565b6200039c81848462000355565b505050565b5b81811015620003c457620003b860008262000385565b600181019050620003a2565b5050565b601f8211156200041357620003dd8162000287565b620003e8846200029c565b81016020851015620003f8578190505b6200041062000407856200029c565b830182620003a1565b50505b505050565b600082821c905092915050565b6000620004386000198460080262000418565b1980831691505092915050565b600062000453838362000425565b9150826002028217905092915050565b6200046e82620001e9565b67ffffffffffffffff8111156200048a5762000489620001f4565b5b62000496825462000252565b620004a3828285620003c8565b600060209050601f831160018114620004db5760008415620004c6578287015190505b620004d2858262000445565b86555062000542565b601f198416620004eb8662000287565b60005b828110156200051557848901518255600182019150602085019450602081019050620004ee565b8683101562000535578489015162000531601f89168262000425565b8355505b6001600288020188555050505b505050505050565b6155b1806200055a6000396000f3fe60806040526004361061027d5760003560e01c80636352211e1161014f578063b94a2102116100c1578063e985e9c51161007a578063e985e9c5146109fc578063ef6fd87814610a39578063f2fde38b14610a76578063f556aeb114610a9f578063f70e72ef14610ac8578063f887ea4014610b055761027d565b8063b94a2102146108c6578063bd4986a0146108f1578063bdb4b8481461092e578063c87b56dd14610959578063d343682614610996578063d7b0398b146109bf5761027d565b80638da5cb5b116101135780638da5cb5b146107c85780639388f12e146107f357806395d89b411461081e57806397016f3f14610849578063a22cb46514610874578063b88d4fde1461089d5761027d565b80636352211e146106de57806366a306d71461071b57806370a082311461074b578063715018a6146107885780638545f4ea1461079f5761027d565b80633ccfd60b116101f35780634f558e79116101ac5780634f558e79146105a55780634f6ccce7146105e257806356e3a1ae1461061f5780635c110a9c1461065c5780635d228b16146106855780635f49663c146106b55761027d565b80633ccfd60b146104ad57806341cb87fc146104c457806342842e0e146104ed57806342966c681461051657806342dd8fcb1461053f5780634c19eae61461057c5761027d565b806318160ddd1161024557806318160ddd1461038d5780631ea89a22146103b85780631f275713146103e157806323b872dd1461041e5780632f745c59146104475780633b189852146104845761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b3146103275780631582391c14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613870565b610b30565b6040516102b691906138b8565b60405180910390f35b3480156102cb57600080fd5b506102d4610c6a565b6040516102e19190613963565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c91906139bb565b610cfc565b60405161031e9190613a29565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613a70565b610d42565b005b34801561035c57600080fd5b5061037760048036038101906103729190613b1f565b610e59565b6040516103849190613bbb565b60405180910390f35b34801561039957600080fd5b506103a2610e83565b6040516103af9190613bbb565b60405180910390f35b3480156103c457600080fd5b506103df60048036038101906103da9190613bd6565b610e90565b005b3480156103ed57600080fd5b5061040860048036038101906104039190613c03565b610f1f565b6040516104159190613c3f565b60405180910390f35b34801561042a57600080fd5b5061044560048036038101906104409190613c5a565b610f4f565b005b34801561045357600080fd5b5061046e60048036038101906104699190613a70565b610faf565b60405161047b9190613bbb565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190613bd6565b611054565b005b3480156104b957600080fd5b506104c26110e3565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b6111f6565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613c5a565b611285565b005b34801561052257600080fd5b5061053d600480360381019061053891906139bb565b6112a5565b005b34801561054b57600080fd5b50610566600480360381019061056191906139bb565b611301565b6040516105739190613bbb565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e9190613cad565b611321565b005b3480156105b157600080fd5b506105cc60048036038101906105c791906139bb565b6114eb565b6040516105d991906138b8565b60405180910390f35b3480156105ee57600080fd5b50610609600480360381019061060491906139bb565b6114fd565b6040516106169190613bbb565b60405180910390f35b34801561062b57600080fd5b50610646600480360381019061064191906139bb565b61156e565b60405161065391906138b8565b60405180910390f35b34801561066857600080fd5b50610683600480360381019061067e9190613d28565b61158e565b005b61069f600480360381019061069a91906139bb565b61168a565b6040516106ac9190613bbb565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d79190613bd6565b6116f0565b005b3480156106ea57600080fd5b50610705600480360381019061070091906139bb565b61177f565b6040516107129190613a29565b60405180910390f35b61073560048036038101906107309190613e9d565b611830565b6040516107429190613bbb565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613bd6565b61197a565b60405161077f9190613bbb565b60405180910390f35b34801561079457600080fd5b5061079d611a31565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906139bb565b611a45565b005b3480156107d457600080fd5b506107dd611a8e565b6040516107ea9190613a29565b60405180910390f35b3480156107ff57600080fd5b50610808611ab8565b6040516108159190613f58565b60405180910390f35b34801561082a57600080fd5b50610833611ade565b6040516108409190613963565b60405180910390f35b34801561085557600080fd5b5061085e611b70565b60405161086b9190613f94565b60405180910390f35b34801561088057600080fd5b5061089b60048036038101906108969190613fdb565b611b96565b005b3480156108a957600080fd5b506108c460048036038101906108bf919061401b565b611bac565b005b3480156108d257600080fd5b506108db611c0e565b6040516108e89190613a29565b60405180910390f35b3480156108fd57600080fd5b50610918600480360381019061091391906139bb565b611c34565b6040516109259190613a29565b60405180910390f35b34801561093a57600080fd5b50610943611cd9565b6040516109509190613bbb565b60405180910390f35b34801561096557600080fd5b50610980600480360381019061097b91906139bb565b611cdf565b60405161098d9190613963565b60405180910390f35b3480156109a257600080fd5b506109bd60048036038101906109b891906139bb565b611f8e565b005b3480156109cb57600080fd5b506109e660048036038101906109e1919061409e565b611fa3565b6040516109f39190613bbb565b60405180910390f35b348015610a0857600080fd5b50610a236004803603810190610a1e919061415c565b611fcf565b604051610a3091906138b8565b60405180910390f35b348015610a4557600080fd5b50610a606004803603810190610a5b91906139bb565b612063565b604051610a6d91906141f1565b60405180910390f35b348015610a8257600080fd5b50610a9d6004803603810190610a989190613bd6565b61210d565b005b348015610aab57600080fd5b50610ac66004803603810190610ac19190613e9d565b612190565b005b348015610ad457600080fd5b50610aef6004803603810190610aea9190613d28565b612289565b604051610afc9190613bbb565b60405180910390f35b348015610b1157600080fd5b50610b1a6122ba565b604051610b279190614234565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bfb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c6357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c799061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061427e565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b5050505050905090565b6000610d07826122e0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4d8261177f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490614321565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ddc61232b565b73ffffffffffffffffffffffffffffffffffffffff161480610e0b5750610e0a81610e0561232b565b611fcf565b5b610e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e41906143b3565b60405180910390fd5b610e548383612333565b505050565b600080610e65886123ec565b9050610e758782888888886124de565b809150509695505050505050565b6000600980549050905090565b610e98612529565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f32919061444b565b604051602081830303815290604052805190602001209050919050565b610f60610f5a61232b565b826125a7565b610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906144e3565b60405180910390fd5b610faa83838361263c565b505050565b6000610fba8361197a565b8210610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff290614575565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61105c612529565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110eb612529565b6002600b5403611130576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611127906145e1565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161116390614632565b60006040518083038185875af1925050503d80600081146111a0576040519150601f19603f3d011682016040523d82523d6000602084013e6111a5565b606091505b50509050806111b357600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111e29190613bbb565b60405180910390a150506001600b81905550565b6111fe612529565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f8da1c48aefffe2a2520f3e707937e3254d532a0905d345e539532599d2a0564c60405160405180910390a250565b6112a083838360405180602001604052806000815250611bac565b505050565b6112b66112b061232b565b826125a7565b6112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906144e3565b60405180910390fd5b6112fe816128a2565b50565b600060116000838152602001908152602001600020805490509050919050565b600061135430876040516020016113399291906146b0565b60405160208183030381529060405280519060200120610f1f565b9050848114611398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138f9061474e565b60405180910390fd5b6000600186868686604051600081526020016040526040516113bd949392919061477d565b6020604051602081039080840390855afa1580156113df573d6000803e3d6000fd5b505050602060405103519050601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114729061485a565b60405180910390fd5b600015156012600089815260200190815260200160002060009054906101000a900460ff161515146114e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d9906148ec565b60405180910390fd5b50505050505050565b60006114f6826129bf565b9050919050565b6000611507610e83565b8210611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f9061497e565b60405180910390fd5b6009828154811061155c5761155b61499e565b5b90600052602060002001549050919050565b60126020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161590614a3f565b60405180910390fd5b6011600082815260200190815260200160002082908060018154018082558091505060019003906000526020600020016000909190919091505580827f67c5bcaefda7c1381ded3fc61dbb8e693cef5b368cd356324bcc2b1aa791448c60405160405180910390a35050565b6000600f5434146116d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c790614aab565b60405180910390fd5b60006116db836123ec565b90506116e78133612a2b565b80915050919050565b6116f8612529565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181e90614b17565b60405180910390fd5b80915050919050565b6000600f543414611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90614aab565b60405180910390fd5b6000611881846123ec565b905061188d8130612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff8111156118e8576118e7613d72565b5b6040519080825280602002602001820160405280156119165781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161193593929190614bf5565b600060405180830381600087803b15801561194f57600080fd5b505af1158015611963573d6000803e3d6000fd5b50505050611970816128a2565b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e190614cac565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611a39612529565b611a436000612b57565b565b611a4d612529565b80600f819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611a839190613bbb565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611aed9061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054611b199061427e565b8015611b665780601f10611b3b57610100808354040283529160200191611b66565b820191906000526020600020905b815481529060010190602001808311611b4957829003601f168201915b5050505050905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611ba8611ba161232b565b8383612c1d565b5050565b611bbd611bb761232b565b836125a7565b611bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf3906144e3565b60405180910390fd5b611c0884848484612d89565b50505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b8152600401611c919190613bbb565b602060405180830381865afa158015611cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd29190614ce1565b9050919050565b600f5481565b6060611d1f6040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878846040518263ffffffff1660e01b8152600401611d7c9190613bbb565b600060405180830381865afa158015611d99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611dc29190614d7e565b9050611e026040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0856040518263ffffffff1660e01b8152600401611e5f9190613bbb565b602060405180830381865afa158015611e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea09190614ce1565b9050611ee06040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612de5565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611f3f93929190614dc7565b600060405180830381865afa158015611f5c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f859190614ea6565b92505050919050565b611f96612529565b611fa08133612a2b565b50565b600080611faf896123ec565b9050611fc088828989898989612e7e565b80915050979650505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016120c09190613bbb565b600060405180830381865afa1580156120dd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121069190614d7e565b9050919050565b612115612529565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612184576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217b90614f61565b60405180910390fd5b61218d81612b57565b50565b612198612529565b6121a28230612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788383600067ffffffffffffffff8111156121fd576121fc613d72565b5b60405190808252806020026020018201604052801561222b5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161224a93929190614bf5565b600060405180830381600087803b15801561226457600080fd5b505af1158015612278573d6000803e3d6000fd5b50505050612285826128a2565b5050565b601160205281600052604060002081815481106122a557600080fd5b90600052602060002001600091509150505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6122e9816129bf565b612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614b17565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166123a68361177f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080601160008481526020019081526020016000208054905011612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90614ff3565b60405180910390fd5b6000601160008481526020019081526020016000206001601160008681526020019081526020016000208054905061247e9190615042565b8154811061248f5761248e61499e565b5b90600052602060002001549050601160008481526020019081526020016000208054806124bf576124be615076565b5b6001900381819060005260206000200160009055905580915050919050565b6124eb8685858585611321565b6124f58533612a2b565b60016012600088815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b61253161232b565b73ffffffffffffffffffffffffffffffffffffffff1661254f611a8e565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259c906150f1565b60405180910390fd5b565b6000806125b38361177f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f557506125f48185611fcf565b5b8061263357508373ffffffffffffffffffffffffffffffffffffffff1661261b84610cfc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661265c8261177f565b73ffffffffffffffffffffffffffffffffffffffff16146126b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a990615183565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271890615215565b60405180910390fd5b61272c838383612fad565b612737600082612333565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127879190615042565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127de9190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461289d838383612fbd565b505050565b60006128ad8261177f565b90506128bb81600084612fad565b6128c6600083612333565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129169190615042565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129bb81600084612fbd565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301c6d035836040518263ffffffff1660e01b8152600401612a869190613bbb565b602060405180830381865afa158015612aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac7919061527e565b612b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afd906152f7565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b4857612b438183612fc2565b612b53565b612b52818361319b565b5b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8290615363565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612d7c91906138b8565b60405180910390a3505050565b612d9484848461263c565b612da0848484846131b9565b612ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd6906153f5565b60405180910390fd5b50505050565b612e7b81604051602401612df99190613963565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613340565b50565b612e8b8785858585611321565b612e958630612a2b565b60016012600089815260200190815260200160002060006101000a81548160ff021916908315150217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788787600067ffffffffffffffff811115612f1c57612f1b613d72565b5b604051908082528060200260200182016040528015612f4a5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b8152600401612f6993929190614bf5565b600060405180830381600087803b158015612f8357600080fd5b505af1158015612f97573d6000803e3d6000fd5b50505050612fa4866128a2565b50505050505050565b612fb8838383613369565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161302890615461565b60405180910390fd5b61303a816129bf565b1561307a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613071906154cd565b60405180910390fd5b61308660008383612fad565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130d69190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461319760008383612fbd565b5050565b6131b582826040518060200160405280600081525061347b565b5050565b60006131da8473ffffffffffffffffffffffffffffffffffffffff166134d6565b15613333578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261320361232b565b8786866040518563ffffffff1660e01b815260040161322594939291906154ed565b6020604051808303816000875af192505050801561326157506040513d601f19601f8201168201806040525081019061325e919061554e565b60015b6132e3573d8060008114613291576040519150601f19603f3d011682016040523d82523d6000602084013e613296565b606091505b5060008151036132db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d2906153f5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613338565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6133748383836134f9565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133b6576133b1816134fe565b6133f5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133f4576133f38382613547565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361343757613432816136b4565b613476565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614613475576134748282613785565b5b5b505050565b6134858383612fc2565b61349260008484846131b9565b6134d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134c8906153f5565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135548461197a565b61355e9190615042565b9050600060086000848152602001908152602001600020549050818114613643576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506136c89190615042565b90506000600a60008481526020019081526020016000205490506000600983815481106136f8576136f761499e565b5b90600052602060002001549050806009838154811061371a5761371961499e565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061376957613768615076565b5b6001900381819060005260206000200160009055905550505050565b60006137908361197a565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384d81613818565b811461385857600080fd5b50565b60008135905061386a81613844565b92915050565b6000602082840312156138865761388561380e565b5b60006138948482850161385b565b91505092915050565b60008115159050919050565b6138b28161389d565b82525050565b60006020820190506138cd60008301846138a9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561390d5780820151818401526020810190506138f2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613935826138d3565b61393f81856138de565b935061394f8185602086016138ef565b61395881613919565b840191505092915050565b6000602082019050818103600083015261397d818461392a565b905092915050565b6000819050919050565b61399881613985565b81146139a357600080fd5b50565b6000813590506139b58161398f565b92915050565b6000602082840312156139d1576139d061380e565b5b60006139df848285016139a6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a13826139e8565b9050919050565b613a2381613a08565b82525050565b6000602082019050613a3e6000830184613a1a565b92915050565b613a4d81613a08565b8114613a5857600080fd5b50565b600081359050613a6a81613a44565b92915050565b60008060408385031215613a8757613a8661380e565b5b6000613a9585828601613a5b565b9250506020613aa6858286016139a6565b9150509250929050565b6000819050919050565b613ac381613ab0565b8114613ace57600080fd5b50565b600081359050613ae081613aba565b92915050565b600060ff82169050919050565b613afc81613ae6565b8114613b0757600080fd5b50565b600081359050613b1981613af3565b92915050565b60008060008060008060c08789031215613b3c57613b3b61380e565b5b6000613b4a89828a016139a6565b9650506020613b5b89828a016139a6565b9550506040613b6c89828a01613ad1565b9450506060613b7d89828a01613b0a565b9350506080613b8e89828a01613ad1565b92505060a0613b9f89828a01613ad1565b9150509295509295509295565b613bb581613985565b82525050565b6000602082019050613bd06000830184613bac565b92915050565b600060208284031215613bec57613beb61380e565b5b6000613bfa84828501613a5b565b91505092915050565b600060208284031215613c1957613c1861380e565b5b6000613c2784828501613ad1565b91505092915050565b613c3981613ab0565b82525050565b6000602082019050613c546000830184613c30565b92915050565b600080600060608486031215613c7357613c7261380e565b5b6000613c8186828701613a5b565b9350506020613c9286828701613a5b565b9250506040613ca3868287016139a6565b9150509250925092565b600080600080600060a08688031215613cc957613cc861380e565b5b6000613cd7888289016139a6565b9550506020613ce888828901613ad1565b9450506040613cf988828901613b0a565b9350506060613d0a88828901613ad1565b9250506080613d1b88828901613ad1565b9150509295509295909350565b60008060408385031215613d3f57613d3e61380e565b5b6000613d4d858286016139a6565b9250506020613d5e858286016139a6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613daa82613919565b810181811067ffffffffffffffff82111715613dc957613dc8613d72565b5b80604052505050565b6000613ddc613804565b9050613de88282613da1565b919050565b600067ffffffffffffffff821115613e0857613e07613d72565b5b613e1182613919565b9050602081019050919050565b82818337600083830152505050565b6000613e40613e3b84613ded565b613dd2565b905082815260208101848484011115613e5c57613e5b613d6d565b5b613e67848285613e1e565b509392505050565b600082601f830112613e8457613e83613d68565b5b8135613e94848260208601613e2d565b91505092915050565b60008060408385031215613eb457613eb361380e565b5b6000613ec2858286016139a6565b925050602083013567ffffffffffffffff811115613ee357613ee2613813565b5b613eef85828601613e6f565b9150509250929050565b6000819050919050565b6000613f1e613f19613f14846139e8565b613ef9565b6139e8565b9050919050565b6000613f3082613f03565b9050919050565b6000613f4282613f25565b9050919050565b613f5281613f37565b82525050565b6000602082019050613f6d6000830184613f49565b92915050565b6000613f7e82613f25565b9050919050565b613f8e81613f73565b82525050565b6000602082019050613fa96000830184613f85565b92915050565b613fb88161389d565b8114613fc357600080fd5b50565b600081359050613fd581613faf565b92915050565b60008060408385031215613ff257613ff161380e565b5b600061400085828601613a5b565b925050602061401185828601613fc6565b9150509250929050565b600080600080608085870312156140355761403461380e565b5b600061404387828801613a5b565b945050602061405487828801613a5b565b9350506040614065878288016139a6565b925050606085013567ffffffffffffffff81111561408657614085613813565b5b61409287828801613e6f565b91505092959194509250565b600080600080600080600060e0888a0312156140bd576140bc61380e565b5b60006140cb8a828b016139a6565b97505060206140dc8a828b016139a6565b965050604088013567ffffffffffffffff8111156140fd576140fc613813565b5b6141098a828b01613e6f565b955050606061411a8a828b01613ad1565b945050608061412b8a828b01613b0a565b93505060a061413c8a828b01613ad1565b92505060c061414d8a828b01613ad1565b91505092959891949750929550565b600080604083850312156141735761417261380e565b5b600061418185828601613a5b565b925050602061419285828601613a5b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60006141c38261419c565b6141cd81856141a7565b93506141dd8185602086016138ef565b6141e681613919565b840191505092915050565b6000602082019050818103600083015261420b81846141b8565b905092915050565b600061421e82613f25565b9050919050565b61422e81614213565b82525050565b60006020820190506142496000830184614225565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061429657607f821691505b6020821081036142a9576142a861424f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061430b6021836138de565b9150614316826142af565b604082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061439d603e836138de565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614414601c836143d3565b915061441f826143de565b601c82019050919050565b6000819050919050565b61444561444082613ab0565b61442a565b82525050565b600061445682614407565b91506144628284614434565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006144cd602e836138de565b91506144d882614471565b604082019050919050565b600060208201905081810360008301526144fc816144c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061455f602b836138de565b915061456a82614503565b604082019050919050565b6000602082019050818103600083015261458e81614552565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145cb601f836138de565b91506145d682614595565b602082019050919050565b600060208201905081810360008301526145fa816145be565b9050919050565b600081905092915050565b50565b600061461c600083614601565b91506146278261460c565b600082019050919050565b600061463d8261460f565b9150819050919050565b60008160601b9050919050565b600061465f82614647565b9050919050565b600061467182614654565b9050919050565b61468961468482613a08565b614666565b82525050565b6000819050919050565b6146aa6146a582613985565b61468f565b82525050565b60006146bc8285614678565b6014820191506146cc8284614699565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b6000614738603c836138de565b9150614743826146dc565b604082019050919050565b600060208201905081810360008301526147678161472b565b9050919050565b61477781613ae6565b82525050565b60006080820190506147926000830187613c30565b61479f602083018661476e565b6147ac6040830185613c30565b6147b96060830184613c30565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b60006148446041836138de565b915061484f826147c2565b606082019050919050565b6000602082019050818103600083015261487381614837565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b60006148d6602b836138de565b91506148e18261487a565b604082019050919050565b60006020820190508181036000830152614905816148c9565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614968602c836138de565b91506149738261490c565b604082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4f6e6c792074686520726f7574696e6720636f6e74726163742063616e20636160008201527f6c6c20746869732066756e6374696f6e00000000000000000000000000000000602082015250565b6000614a296030836138de565b9150614a34826149cd565b604082019050919050565b60006020820190508181036000830152614a5881614a1c565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614a95601e836138de565b9150614aa082614a5f565b602082019050919050565b60006020820190508181036000830152614ac481614a88565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b016018836138de565b9150614b0c82614acb565b602082019050919050565b60006020820190508181036000830152614b3081614af4565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614b6c81613985565b82525050565b6000614b7e8383614b63565b60208301905092915050565b6000602082019050919050565b6000614ba282614b37565b614bac8185614b42565b9350614bb783614b53565b8060005b83811015614be8578151614bcf8882614b72565b9750614bda83614b8a565b925050600181019050614bbb565b5085935050505092915050565b6000606082019050614c0a6000830186613bac565b8181036020830152614c1c81856141b8565b90508181036040830152614c308184614b97565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614c966029836138de565b9150614ca182614c3a565b604082019050919050565b60006020820190508181036000830152614cc581614c89565b9050919050565b600081519050614cdb81613a44565b92915050565b600060208284031215614cf757614cf661380e565b5b6000614d0584828501614ccc565b91505092915050565b6000614d21614d1c84613ded565b613dd2565b905082815260208101848484011115614d3d57614d3c613d6d565b5b614d488482856138ef565b509392505050565b600082601f830112614d6557614d64613d68565b5b8151614d75848260208601614d0e565b91505092915050565b600060208284031215614d9457614d9361380e565b5b600082015167ffffffffffffffff811115614db257614db1613813565b5b614dbe84828501614d50565b91505092915050565b6000606082019050614ddc6000830186613bac565b8181036020830152614dee81856141b8565b9050614dfd6040830184613a1a565b949350505050565b600067ffffffffffffffff821115614e2057614e1f613d72565b5b614e2982613919565b9050602081019050919050565b6000614e49614e4484614e05565b613dd2565b905082815260208101848484011115614e6557614e64613d6d565b5b614e708482856138ef565b509392505050565b600082601f830112614e8d57614e8c613d68565b5b8151614e9d848260208601614e36565b91505092915050565b600060208284031215614ebc57614ebb61380e565b5b600082015167ffffffffffffffff811115614eda57614ed9613813565b5b614ee684828501614e78565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614f4b6026836138de565b9150614f5682614eef565b604082019050919050565b60006020820190508181036000830152614f7a81614f3e565b9050919050565b7f546865726520617265206e6f20756e6d696e74656420726f7574656420746f6b60008201527f656e2069647320746f206d696e74000000000000000000000000000000000000602082015250565b6000614fdd602e836138de565b9150614fe882614f81565b604082019050919050565b6000602082019050818103600083015261500c81614fd0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061504d82613985565b915061505883613985565b92508282039050818111156150705761506f615013565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150db6020836138de565b91506150e6826150a5565b602082019050919050565b6000602082019050818103600083015261510a816150ce565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061516d6025836138de565b915061517882615111565b604082019050919050565b6000602082019050818103600083015261519c81615160565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006151ff6024836138de565b915061520a826151a3565b604082019050919050565b6000602082019050818103600083015261522e816151f2565b9050919050565b600061524082613985565b915061524b83613985565b925082820190508082111561526357615262615013565b5b92915050565b60008151905061527881613faf565b92915050565b6000602082840312156152945761529361380e565b5b60006152a284828501615269565b91505092915050565b7f5468697320504b5020686173206e6f74206265656e20726f7574656420796574600082015250565b60006152e16020836138de565b91506152ec826152ab565b602082019050919050565b60006020820190508181036000830152615310816152d4565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061534d6019836138de565b915061535882615317565b602082019050919050565b6000602082019050818103600083015261537c81615340565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006153df6032836138de565b91506153ea82615383565b604082019050919050565b6000602082019050818103600083015261540e816153d2565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061544b6020836138de565b915061545682615415565b602082019050919050565b6000602082019050818103600083015261547a8161543e565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006154b7601c836138de565b91506154c282615481565b602082019050919050565b600060208201905081810360008301526154e6816154aa565b9050919050565b60006080820190506155026000830187613a1a565b61550f6020830186613a1a565b61551c6040830185613bac565b818103606083015261552e81846141b8565b905095945050505050565b60008151905061554881613844565b92915050565b6000602082840312156155645761556361380e565b5b600061557284828501615539565b9150509291505056fea2646970667358221220e61f7354009e051db803552839acecd41aa1d98eb1c52fffb8612e975733b70164736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c80636352211e1161014f578063b94a2102116100c1578063e985e9c51161007a578063e985e9c5146109fc578063ef6fd87814610a39578063f2fde38b14610a76578063f556aeb114610a9f578063f70e72ef14610ac8578063f887ea4014610b055761027d565b8063b94a2102146108c6578063bd4986a0146108f1578063bdb4b8481461092e578063c87b56dd14610959578063d343682614610996578063d7b0398b146109bf5761027d565b80638da5cb5b116101135780638da5cb5b146107c85780639388f12e146107f357806395d89b411461081e57806397016f3f14610849578063a22cb46514610874578063b88d4fde1461089d5761027d565b80636352211e146106de57806366a306d71461071b57806370a082311461074b578063715018a6146107885780638545f4ea1461079f5761027d565b80633ccfd60b116101f35780634f558e79116101ac5780634f558e79146105a55780634f6ccce7146105e257806356e3a1ae1461061f5780635c110a9c1461065c5780635d228b16146106855780635f49663c146106b55761027d565b80633ccfd60b146104ad57806341cb87fc146104c457806342842e0e146104ed57806342966c681461051657806342dd8fcb1461053f5780634c19eae61461057c5761027d565b806318160ddd1161024557806318160ddd1461038d5780631ea89a22146103b85780631f275713146103e157806323b872dd1461041e5780632f745c59146104475780633b189852146104845761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b3146103275780631582391c14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613870565b610b30565b6040516102b691906138b8565b60405180910390f35b3480156102cb57600080fd5b506102d4610c6a565b6040516102e19190613963565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c91906139bb565b610cfc565b60405161031e9190613a29565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613a70565b610d42565b005b34801561035c57600080fd5b5061037760048036038101906103729190613b1f565b610e59565b6040516103849190613bbb565b60405180910390f35b34801561039957600080fd5b506103a2610e83565b6040516103af9190613bbb565b60405180910390f35b3480156103c457600080fd5b506103df60048036038101906103da9190613bd6565b610e90565b005b3480156103ed57600080fd5b5061040860048036038101906104039190613c03565b610f1f565b6040516104159190613c3f565b60405180910390f35b34801561042a57600080fd5b5061044560048036038101906104409190613c5a565b610f4f565b005b34801561045357600080fd5b5061046e60048036038101906104699190613a70565b610faf565b60405161047b9190613bbb565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190613bd6565b611054565b005b3480156104b957600080fd5b506104c26110e3565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b6111f6565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613c5a565b611285565b005b34801561052257600080fd5b5061053d600480360381019061053891906139bb565b6112a5565b005b34801561054b57600080fd5b50610566600480360381019061056191906139bb565b611301565b6040516105739190613bbb565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e9190613cad565b611321565b005b3480156105b157600080fd5b506105cc60048036038101906105c791906139bb565b6114eb565b6040516105d991906138b8565b60405180910390f35b3480156105ee57600080fd5b50610609600480360381019061060491906139bb565b6114fd565b6040516106169190613bbb565b60405180910390f35b34801561062b57600080fd5b50610646600480360381019061064191906139bb565b61156e565b60405161065391906138b8565b60405180910390f35b34801561066857600080fd5b50610683600480360381019061067e9190613d28565b61158e565b005b61069f600480360381019061069a91906139bb565b61168a565b6040516106ac9190613bbb565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d79190613bd6565b6116f0565b005b3480156106ea57600080fd5b50610705600480360381019061070091906139bb565b61177f565b6040516107129190613a29565b60405180910390f35b61073560048036038101906107309190613e9d565b611830565b6040516107429190613bbb565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613bd6565b61197a565b60405161077f9190613bbb565b60405180910390f35b34801561079457600080fd5b5061079d611a31565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906139bb565b611a45565b005b3480156107d457600080fd5b506107dd611a8e565b6040516107ea9190613a29565b60405180910390f35b3480156107ff57600080fd5b50610808611ab8565b6040516108159190613f58565b60405180910390f35b34801561082a57600080fd5b50610833611ade565b6040516108409190613963565b60405180910390f35b34801561085557600080fd5b5061085e611b70565b60405161086b9190613f94565b60405180910390f35b34801561088057600080fd5b5061089b60048036038101906108969190613fdb565b611b96565b005b3480156108a957600080fd5b506108c460048036038101906108bf919061401b565b611bac565b005b3480156108d257600080fd5b506108db611c0e565b6040516108e89190613a29565b60405180910390f35b3480156108fd57600080fd5b50610918600480360381019061091391906139bb565b611c34565b6040516109259190613a29565b60405180910390f35b34801561093a57600080fd5b50610943611cd9565b6040516109509190613bbb565b60405180910390f35b34801561096557600080fd5b50610980600480360381019061097b91906139bb565b611cdf565b60405161098d9190613963565b60405180910390f35b3480156109a257600080fd5b506109bd60048036038101906109b891906139bb565b611f8e565b005b3480156109cb57600080fd5b506109e660048036038101906109e1919061409e565b611fa3565b6040516109f39190613bbb565b60405180910390f35b348015610a0857600080fd5b50610a236004803603810190610a1e919061415c565b611fcf565b604051610a3091906138b8565b60405180910390f35b348015610a4557600080fd5b50610a606004803603810190610a5b91906139bb565b612063565b604051610a6d91906141f1565b60405180910390f35b348015610a8257600080fd5b50610a9d6004803603810190610a989190613bd6565b61210d565b005b348015610aab57600080fd5b50610ac66004803603810190610ac19190613e9d565b612190565b005b348015610ad457600080fd5b50610aef6004803603810190610aea9190613d28565b612289565b604051610afc9190613bbb565b60405180910390f35b348015610b1157600080fd5b50610b1a6122ba565b604051610b279190614234565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bfb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c6357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c799061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061427e565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b5050505050905090565b6000610d07826122e0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4d8261177f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490614321565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ddc61232b565b73ffffffffffffffffffffffffffffffffffffffff161480610e0b5750610e0a81610e0561232b565b611fcf565b5b610e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e41906143b3565b60405180910390fd5b610e548383612333565b505050565b600080610e65886123ec565b9050610e758782888888886124de565b809150509695505050505050565b6000600980549050905090565b610e98612529565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f32919061444b565b604051602081830303815290604052805190602001209050919050565b610f60610f5a61232b565b826125a7565b610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906144e3565b60405180910390fd5b610faa83838361263c565b505050565b6000610fba8361197a565b8210610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff290614575565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61105c612529565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110eb612529565b6002600b5403611130576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611127906145e1565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161116390614632565b60006040518083038185875af1925050503d80600081146111a0576040519150601f19603f3d011682016040523d82523d6000602084013e6111a5565b606091505b50509050806111b357600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111e29190613bbb565b60405180910390a150506001600b81905550565b6111fe612529565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f8da1c48aefffe2a2520f3e707937e3254d532a0905d345e539532599d2a0564c60405160405180910390a250565b6112a083838360405180602001604052806000815250611bac565b505050565b6112b66112b061232b565b826125a7565b6112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906144e3565b60405180910390fd5b6112fe816128a2565b50565b600060116000838152602001908152602001600020805490509050919050565b600061135430876040516020016113399291906146b0565b60405160208183030381529060405280519060200120610f1f565b9050848114611398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138f9061474e565b60405180910390fd5b6000600186868686604051600081526020016040526040516113bd949392919061477d565b6020604051602081039080840390855afa1580156113df573d6000803e3d6000fd5b505050602060405103519050601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114729061485a565b60405180910390fd5b600015156012600089815260200190815260200160002060009054906101000a900460ff161515146114e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d9906148ec565b60405180910390fd5b50505050505050565b60006114f6826129bf565b9050919050565b6000611507610e83565b8210611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f9061497e565b60405180910390fd5b6009828154811061155c5761155b61499e565b5b90600052602060002001549050919050565b60126020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161590614a3f565b60405180910390fd5b6011600082815260200190815260200160002082908060018154018082558091505060019003906000526020600020016000909190919091505580827f67c5bcaefda7c1381ded3fc61dbb8e693cef5b368cd356324bcc2b1aa791448c60405160405180910390a35050565b6000600f5434146116d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c790614aab565b60405180910390fd5b60006116db836123ec565b90506116e78133612a2b565b80915050919050565b6116f8612529565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181e90614b17565b60405180910390fd5b80915050919050565b6000600f543414611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90614aab565b60405180910390fd5b6000611881846123ec565b905061188d8130612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff8111156118e8576118e7613d72565b5b6040519080825280602002602001820160405280156119165781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161193593929190614bf5565b600060405180830381600087803b15801561194f57600080fd5b505af1158015611963573d6000803e3d6000fd5b50505050611970816128a2565b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e190614cac565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611a39612529565b611a436000612b57565b565b611a4d612529565b80600f819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611a839190613bbb565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611aed9061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054611b199061427e565b8015611b665780601f10611b3b57610100808354040283529160200191611b66565b820191906000526020600020905b815481529060010190602001808311611b4957829003601f168201915b5050505050905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611ba8611ba161232b565b8383612c1d565b5050565b611bbd611bb761232b565b836125a7565b611bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf3906144e3565b60405180910390fd5b611c0884848484612d89565b50505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b8152600401611c919190613bbb565b602060405180830381865afa158015611cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd29190614ce1565b9050919050565b600f5481565b6060611d1f6040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878846040518263ffffffff1660e01b8152600401611d7c9190613bbb565b600060405180830381865afa158015611d99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611dc29190614d7e565b9050611e026040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0856040518263ffffffff1660e01b8152600401611e5f9190613bbb565b602060405180830381865afa158015611e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea09190614ce1565b9050611ee06040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612de5565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611f3f93929190614dc7565b600060405180830381865afa158015611f5c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f859190614ea6565b92505050919050565b611f96612529565b611fa08133612a2b565b50565b600080611faf896123ec565b9050611fc088828989898989612e7e565b80915050979650505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016120c09190613bbb565b600060405180830381865afa1580156120dd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121069190614d7e565b9050919050565b612115612529565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612184576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217b90614f61565b60405180910390fd5b61218d81612b57565b50565b612198612529565b6121a28230612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788383600067ffffffffffffffff8111156121fd576121fc613d72565b5b60405190808252806020026020018201604052801561222b5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161224a93929190614bf5565b600060405180830381600087803b15801561226457600080fd5b505af1158015612278573d6000803e3d6000fd5b50505050612285826128a2565b5050565b601160205281600052604060002081815481106122a557600080fd5b90600052602060002001600091509150505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6122e9816129bf565b612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614b17565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166123a68361177f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080601160008481526020019081526020016000208054905011612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90614ff3565b60405180910390fd5b6000601160008481526020019081526020016000206001601160008681526020019081526020016000208054905061247e9190615042565b8154811061248f5761248e61499e565b5b90600052602060002001549050601160008481526020019081526020016000208054806124bf576124be615076565b5b6001900381819060005260206000200160009055905580915050919050565b6124eb8685858585611321565b6124f58533612a2b565b60016012600088815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b61253161232b565b73ffffffffffffffffffffffffffffffffffffffff1661254f611a8e565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259c906150f1565b60405180910390fd5b565b6000806125b38361177f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f557506125f48185611fcf565b5b8061263357508373ffffffffffffffffffffffffffffffffffffffff1661261b84610cfc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661265c8261177f565b73ffffffffffffffffffffffffffffffffffffffff16146126b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a990615183565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271890615215565b60405180910390fd5b61272c838383612fad565b612737600082612333565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127879190615042565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127de9190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461289d838383612fbd565b505050565b60006128ad8261177f565b90506128bb81600084612fad565b6128c6600083612333565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129169190615042565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129bb81600084612fbd565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301c6d035836040518263ffffffff1660e01b8152600401612a869190613bbb565b602060405180830381865afa158015612aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac7919061527e565b612b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afd906152f7565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b4857612b438183612fc2565b612b53565b612b52818361319b565b5b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8290615363565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612d7c91906138b8565b60405180910390a3505050565b612d9484848461263c565b612da0848484846131b9565b612ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd6906153f5565b60405180910390fd5b50505050565b612e7b81604051602401612df99190613963565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613340565b50565b612e8b8785858585611321565b612e958630612a2b565b60016012600089815260200190815260200160002060006101000a81548160ff021916908315150217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788787600067ffffffffffffffff811115612f1c57612f1b613d72565b5b604051908082528060200260200182016040528015612f4a5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b8152600401612f6993929190614bf5565b600060405180830381600087803b158015612f8357600080fd5b505af1158015612f97573d6000803e3d6000fd5b50505050612fa4866128a2565b50505050505050565b612fb8838383613369565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161302890615461565b60405180910390fd5b61303a816129bf565b1561307a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613071906154cd565b60405180910390fd5b61308660008383612fad565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130d69190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461319760008383612fbd565b5050565b6131b582826040518060200160405280600081525061347b565b5050565b60006131da8473ffffffffffffffffffffffffffffffffffffffff166134d6565b15613333578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261320361232b565b8786866040518563ffffffff1660e01b815260040161322594939291906154ed565b6020604051808303816000875af192505050801561326157506040513d601f19601f8201168201806040525081019061325e919061554e565b60015b6132e3573d8060008114613291576040519150601f19603f3d011682016040523d82523d6000602084013e613296565b606091505b5060008151036132db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d2906153f5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613338565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6133748383836134f9565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133b6576133b1816134fe565b6133f5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133f4576133f38382613547565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361343757613432816136b4565b613476565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614613475576134748282613785565b5b5b505050565b6134858383612fc2565b61349260008484846131b9565b6134d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134c8906153f5565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135548461197a565b61355e9190615042565b9050600060086000848152602001908152602001600020549050818114613643576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506136c89190615042565b90506000600a60008481526020019081526020016000205490506000600983815481106136f8576136f761499e565b5b90600052602060002001549050806009838154811061371a5761371961499e565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061376957613768615076565b5b6001900381819060005260206000200160009055905550505050565b60006137908361197a565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384d81613818565b811461385857600080fd5b50565b60008135905061386a81613844565b92915050565b6000602082840312156138865761388561380e565b5b60006138948482850161385b565b91505092915050565b60008115159050919050565b6138b28161389d565b82525050565b60006020820190506138cd60008301846138a9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561390d5780820151818401526020810190506138f2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613935826138d3565b61393f81856138de565b935061394f8185602086016138ef565b61395881613919565b840191505092915050565b6000602082019050818103600083015261397d818461392a565b905092915050565b6000819050919050565b61399881613985565b81146139a357600080fd5b50565b6000813590506139b58161398f565b92915050565b6000602082840312156139d1576139d061380e565b5b60006139df848285016139a6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a13826139e8565b9050919050565b613a2381613a08565b82525050565b6000602082019050613a3e6000830184613a1a565b92915050565b613a4d81613a08565b8114613a5857600080fd5b50565b600081359050613a6a81613a44565b92915050565b60008060408385031215613a8757613a8661380e565b5b6000613a9585828601613a5b565b9250506020613aa6858286016139a6565b9150509250929050565b6000819050919050565b613ac381613ab0565b8114613ace57600080fd5b50565b600081359050613ae081613aba565b92915050565b600060ff82169050919050565b613afc81613ae6565b8114613b0757600080fd5b50565b600081359050613b1981613af3565b92915050565b60008060008060008060c08789031215613b3c57613b3b61380e565b5b6000613b4a89828a016139a6565b9650506020613b5b89828a016139a6565b9550506040613b6c89828a01613ad1565b9450506060613b7d89828a01613b0a565b9350506080613b8e89828a01613ad1565b92505060a0613b9f89828a01613ad1565b9150509295509295509295565b613bb581613985565b82525050565b6000602082019050613bd06000830184613bac565b92915050565b600060208284031215613bec57613beb61380e565b5b6000613bfa84828501613a5b565b91505092915050565b600060208284031215613c1957613c1861380e565b5b6000613c2784828501613ad1565b91505092915050565b613c3981613ab0565b82525050565b6000602082019050613c546000830184613c30565b92915050565b600080600060608486031215613c7357613c7261380e565b5b6000613c8186828701613a5b565b9350506020613c9286828701613a5b565b9250506040613ca3868287016139a6565b9150509250925092565b600080600080600060a08688031215613cc957613cc861380e565b5b6000613cd7888289016139a6565b9550506020613ce888828901613ad1565b9450506040613cf988828901613b0a565b9350506060613d0a88828901613ad1565b9250506080613d1b88828901613ad1565b9150509295509295909350565b60008060408385031215613d3f57613d3e61380e565b5b6000613d4d858286016139a6565b9250506020613d5e858286016139a6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613daa82613919565b810181811067ffffffffffffffff82111715613dc957613dc8613d72565b5b80604052505050565b6000613ddc613804565b9050613de88282613da1565b919050565b600067ffffffffffffffff821115613e0857613e07613d72565b5b613e1182613919565b9050602081019050919050565b82818337600083830152505050565b6000613e40613e3b84613ded565b613dd2565b905082815260208101848484011115613e5c57613e5b613d6d565b5b613e67848285613e1e565b509392505050565b600082601f830112613e8457613e83613d68565b5b8135613e94848260208601613e2d565b91505092915050565b60008060408385031215613eb457613eb361380e565b5b6000613ec2858286016139a6565b925050602083013567ffffffffffffffff811115613ee357613ee2613813565b5b613eef85828601613e6f565b9150509250929050565b6000819050919050565b6000613f1e613f19613f14846139e8565b613ef9565b6139e8565b9050919050565b6000613f3082613f03565b9050919050565b6000613f4282613f25565b9050919050565b613f5281613f37565b82525050565b6000602082019050613f6d6000830184613f49565b92915050565b6000613f7e82613f25565b9050919050565b613f8e81613f73565b82525050565b6000602082019050613fa96000830184613f85565b92915050565b613fb88161389d565b8114613fc357600080fd5b50565b600081359050613fd581613faf565b92915050565b60008060408385031215613ff257613ff161380e565b5b600061400085828601613a5b565b925050602061401185828601613fc6565b9150509250929050565b600080600080608085870312156140355761403461380e565b5b600061404387828801613a5b565b945050602061405487828801613a5b565b9350506040614065878288016139a6565b925050606085013567ffffffffffffffff81111561408657614085613813565b5b61409287828801613e6f565b91505092959194509250565b600080600080600080600060e0888a0312156140bd576140bc61380e565b5b60006140cb8a828b016139a6565b97505060206140dc8a828b016139a6565b965050604088013567ffffffffffffffff8111156140fd576140fc613813565b5b6141098a828b01613e6f565b955050606061411a8a828b01613ad1565b945050608061412b8a828b01613b0a565b93505060a061413c8a828b01613ad1565b92505060c061414d8a828b01613ad1565b91505092959891949750929550565b600080604083850312156141735761417261380e565b5b600061418185828601613a5b565b925050602061419285828601613a5b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60006141c38261419c565b6141cd81856141a7565b93506141dd8185602086016138ef565b6141e681613919565b840191505092915050565b6000602082019050818103600083015261420b81846141b8565b905092915050565b600061421e82613f25565b9050919050565b61422e81614213565b82525050565b60006020820190506142496000830184614225565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061429657607f821691505b6020821081036142a9576142a861424f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061430b6021836138de565b9150614316826142af565b604082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061439d603e836138de565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614414601c836143d3565b915061441f826143de565b601c82019050919050565b6000819050919050565b61444561444082613ab0565b61442a565b82525050565b600061445682614407565b91506144628284614434565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006144cd602e836138de565b91506144d882614471565b604082019050919050565b600060208201905081810360008301526144fc816144c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061455f602b836138de565b915061456a82614503565b604082019050919050565b6000602082019050818103600083015261458e81614552565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145cb601f836138de565b91506145d682614595565b602082019050919050565b600060208201905081810360008301526145fa816145be565b9050919050565b600081905092915050565b50565b600061461c600083614601565b91506146278261460c565b600082019050919050565b600061463d8261460f565b9150819050919050565b60008160601b9050919050565b600061465f82614647565b9050919050565b600061467182614654565b9050919050565b61468961468482613a08565b614666565b82525050565b6000819050919050565b6146aa6146a582613985565b61468f565b82525050565b60006146bc8285614678565b6014820191506146cc8284614699565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b6000614738603c836138de565b9150614743826146dc565b604082019050919050565b600060208201905081810360008301526147678161472b565b9050919050565b61477781613ae6565b82525050565b60006080820190506147926000830187613c30565b61479f602083018661476e565b6147ac6040830185613c30565b6147b96060830184613c30565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b60006148446041836138de565b915061484f826147c2565b606082019050919050565b6000602082019050818103600083015261487381614837565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b60006148d6602b836138de565b91506148e18261487a565b604082019050919050565b60006020820190508181036000830152614905816148c9565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614968602c836138de565b91506149738261490c565b604082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4f6e6c792074686520726f7574696e6720636f6e74726163742063616e20636160008201527f6c6c20746869732066756e6374696f6e00000000000000000000000000000000602082015250565b6000614a296030836138de565b9150614a34826149cd565b604082019050919050565b60006020820190508181036000830152614a5881614a1c565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614a95601e836138de565b9150614aa082614a5f565b602082019050919050565b60006020820190508181036000830152614ac481614a88565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b016018836138de565b9150614b0c82614acb565b602082019050919050565b60006020820190508181036000830152614b3081614af4565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614b6c81613985565b82525050565b6000614b7e8383614b63565b60208301905092915050565b6000602082019050919050565b6000614ba282614b37565b614bac8185614b42565b9350614bb783614b53565b8060005b83811015614be8578151614bcf8882614b72565b9750614bda83614b8a565b925050600181019050614bbb565b5085935050505092915050565b6000606082019050614c0a6000830186613bac565b8181036020830152614c1c81856141b8565b90508181036040830152614c308184614b97565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614c966029836138de565b9150614ca182614c3a565b604082019050919050565b60006020820190508181036000830152614cc581614c89565b9050919050565b600081519050614cdb81613a44565b92915050565b600060208284031215614cf757614cf661380e565b5b6000614d0584828501614ccc565b91505092915050565b6000614d21614d1c84613ded565b613dd2565b905082815260208101848484011115614d3d57614d3c613d6d565b5b614d488482856138ef565b509392505050565b600082601f830112614d6557614d64613d68565b5b8151614d75848260208601614d0e565b91505092915050565b600060208284031215614d9457614d9361380e565b5b600082015167ffffffffffffffff811115614db257614db1613813565b5b614dbe84828501614d50565b91505092915050565b6000606082019050614ddc6000830186613bac565b8181036020830152614dee81856141b8565b9050614dfd6040830184613a1a565b949350505050565b600067ffffffffffffffff821115614e2057614e1f613d72565b5b614e2982613919565b9050602081019050919050565b6000614e49614e4484614e05565b613dd2565b905082815260208101848484011115614e6557614e64613d6d565b5b614e708482856138ef565b509392505050565b600082601f830112614e8d57614e8c613d68565b5b8151614e9d848260208601614e36565b91505092915050565b600060208284031215614ebc57614ebb61380e565b5b600082015167ffffffffffffffff811115614eda57614ed9613813565b5b614ee684828501614e78565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614f4b6026836138de565b9150614f5682614eef565b604082019050919050565b60006020820190508181036000830152614f7a81614f3e565b9050919050565b7f546865726520617265206e6f20756e6d696e74656420726f7574656420746f6b60008201527f656e2069647320746f206d696e74000000000000000000000000000000000000602082015250565b6000614fdd602e836138de565b9150614fe882614f81565b604082019050919050565b6000602082019050818103600083015261500c81614fd0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061504d82613985565b915061505883613985565b92508282039050818111156150705761506f615013565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150db6020836138de565b91506150e6826150a5565b602082019050919050565b6000602082019050818103600083015261510a816150ce565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061516d6025836138de565b915061517882615111565b604082019050919050565b6000602082019050818103600083015261519c81615160565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006151ff6024836138de565b915061520a826151a3565b604082019050919050565b6000602082019050818103600083015261522e816151f2565b9050919050565b600061524082613985565b915061524b83613985565b925082820190508082111561526357615262615013565b5b92915050565b60008151905061527881613faf565b92915050565b6000602082840312156152945761529361380e565b5b60006152a284828501615269565b91505092915050565b7f5468697320504b5020686173206e6f74206265656e20726f7574656420796574600082015250565b60006152e16020836138de565b91506152ec826152ab565b602082019050919050565b60006020820190508181036000830152615310816152d4565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061534d6019836138de565b915061535882615317565b602082019050919050565b6000602082019050818103600083015261537c81615340565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006153df6032836138de565b91506153ea82615383565b604082019050919050565b6000602082019050818103600083015261540e816153d2565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061544b6020836138de565b915061545682615415565b602082019050919050565b6000602082019050818103600083015261547a8161543e565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006154b7601c836138de565b91506154c282615481565b602082019050919050565b600060208201905081810360008301526154e6816154aa565b9050919050565b60006080820190506155026000830187613a1a565b61550f6020830186613a1a565b61551c6040830185613bac565b818103606083015261552e81846141b8565b905095945050505050565b60008151905061554881613844565b92915050565b6000602082840312156155645761556361380e565b5b600061557284828501615539565b9150509291505056fea2646970667358221220e61f7354009e051db803552839acecd41aa1d98eb1c52fffb8612e975733b70164736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"routerAddress","type":"address"}],"name":"RouterAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurnNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"getUnmintedRoutedTokenIdCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurnNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurnSpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"mintNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintSpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"pkpRouted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract PubkeyRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"}],"name":"setRouterAddress","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"unmintedRoutedTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/PKPNFTMetadata.json b/deployments/lit_175177/PKPNFTMetadata.json deleted file mode 100644 index e378a9f..0000000 --- a/deployments/lit_175177/PKPNFTMetadata.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x47A3F03f38d7c059D6Aacf6c9f9A5279Ffda60fa","bytecode":"0x608060405234801561001057600080fd5b506117de806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"buffer","type":"bytes"}],"name":"bytesToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"address","name":"ethAddress","type":"address"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/PKPPermissions.json b/deployments/lit_175177/PKPPermissions.json deleted file mode 100644 index 2843c2f..0000000 --- a/deployments/lit_175177/PKPPermissions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x8b6F1c0C6C6a01f767E04DaC1C67bB76bF5DC9e4","bytecode":"0x60806040523480156200001157600080fd5b5060405162005087380380620050878339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b614e7080620002176000396000f3fe608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea26469706673582212204f8a2910f560efadc643fb8c043d4f86c1738e61127cd1d5bf70d40aa52307f764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea26469706673582212204f8a2910f560efadc643fb8c043d4f86c1738e61127cd1d5bf70d40aa52307f764736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"userPubkey","type":"bytes"}],"name":"PermittedAuthMethodAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"}],"name":"PermittedAuthMethodRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"group","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootHashUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod","name":"authMethod","type":"tuple"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"addPermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"authMethods","outputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getAuthMethodId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedActions","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"maxScopeId","type":"uint256"}],"name":"getPermittedAuthMethodScopes","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAuthMethods","outputs":[{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getTokenIdsForAuthMethod","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getUserPubkeyForAuthMethod","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"isPermittedAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isPermittedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"isPermittedAuthMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"isPermittedAuthMethodScopePresent","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"removePermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"removePermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"removePermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"removePermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verifyState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool[]","name":"proofFlags","type":"bool[]"},{"internalType":"bytes32[]","name":"leaves","type":"bytes32[]"}],"name":"verifyStates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/PubkeyRouter.json b/deployments/lit_175177/PubkeyRouter.json deleted file mode 100644 index 64bbd1d..0000000 --- a/deployments/lit_175177/PubkeyRouter.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x8adCcA2C39cedF732E2a67f7580E74C33f317Ea2","bytecode":"0x60806040523480156200001157600080fd5b5060405162002909380380620029098339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b6126f280620002176000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063de18a50811610066578063de18a5081461025f578063ef6fd8781461028f578063f2fde38b146102bf578063ffa2e953146102db576100ea565b80638da5cb5b146101df578063b3fe5cf2146101fd578063bd4986a01461022f576100ea565b8063583cb30a116100c8578063583cb30a1461016b5780636edad78714610187578063715018a6146101a35780637bd3e3f6146101ad576100ea565b806301c6d035146100ef578063176354fd1461011f57806325c836f91461013b575b600080fd5b6101096004803603810190610104919061170f565b6102f9565b6040516101169190611757565b60405180910390f35b610139600480360381019061013491906117d0565b61046e565b005b6101556004803603810190610150919061170f565b6104f1565b60405161016291906118fb565b60405180910390f35b61018560048036038101906101809190611a52565b610610565b005b6101a1600480360381019061019c9190611a52565b610e20565b005b6101ab610f8d565b005b6101c760048036038101906101c2919061170f565b610fa1565b6040516101d693929190611b3d565b60405180910390f35b6101e7611073565b6040516101f49190611b7b565b60405180910390f35b6102176004803603810190610212919061170f565b61109c565b60405161022693929190611b96565b60405180910390f35b6102496004803603810190610244919061170f565b6111c2565b6040516102569190611b7b565b60405180910390f35b610279600480360381019061027491906117d0565b6112bd565b6040516102869190611bd4565b60405180910390f35b6102a960048036038101906102a4919061170f565b6112d5565b6040516102b69190611bef565b60405180910390f35b6102d960048036038101906102d491906117d0565b61137d565b005b6102e3611400565b6040516102f09190611c70565b60405180910390f35b6000806002600084815260200190815260200160002060405180606001604052908160008201805461032a90611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461035690611cba565b80156103a35780601f10610378576101008083540402835291602001916103a3565b820191906000526020600020905b81548152906001019060200180831161038657829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050905060008160000151511415801561042957506000816040015114155b80156104665750600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614155b915050919050565b610476611426565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc7ff7959ecbc7f4d8d4a9e6afe9dff66f0e84d0707ee870524fe965872ab6e50816040516104e69190611b7b565b60405180910390a150565b6104f961168e565b6002600083815260200190815260200160002060405180606001604052908160008201805461052790611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461055390611cba565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820154815250509050919050565b600082905060008173ffffffffffffffffffffffffffffffffffffffff16635081f66f336040518263ffffffff1660e01b81526004016106509190611b7b565b602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611d00565b90508173ffffffffffffffffffffffffffffffffffffffff166340550a1c826040518263ffffffff1660e01b81526004016106cc9190611b7b565b602060405180830381865afa1580156106e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070d9190611d59565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074390611e09565b60405180910390fd5b6003600087815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490611e9b565b60405180910390fd5b600060036000888152602001908152602001600020600301540361098257848051906020012060001c8614610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90611f2d565b60405180910390fd5b8460036000888152602001908152602001600020600001600001908161087d91906120ef565b50836003600088815260200190815260200160002060000160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260036000888152602001908152602001600020600001600201819055508173ffffffffffffffffffffffffffffffffffffffff1663dd21d6266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096391906121d6565b6003600088815260200190815260200160002060040181905550610b2c565b6003600087815260200190815260200160002060000160000180546109a690611cba565b905085511480156109ea5750600360008781526020019081526020016000206000016000016040516109d89190612291565b60405180910390208580519060200120145b610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a209061231a565b60405180910390fd5b6003600087815260200190815260200160002060000160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790612386565b60405180910390fd5b60036000878152602001908152602001600020600001600201548314610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b22906123f2565b60405180910390fd5b5b60016003600088815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600360008781526020019081526020016000206003016000815480929190610bbf90612441565b91905055503373ffffffffffffffffffffffffffffffffffffffff16867f55a9294995c030f731a7eefced80c512d4bb6826c506f230021a7320ccc1d172878787604051610c0f93929190611b3d565b60405180910390a360036000878152602001908152602001600020600401546003600088815260200190815260200160002060030154118015610c585750610c56866102f9565b155b15610e185784600260008881526020019081526020016000206000019081610c8091906120ef565b50836002600088815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260008881526020019081526020016000206002018190555060028303610d4c576000610d04876111c2565b905086600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c87856040518363ffffffff1660e01b8152600401610da9929190612489565b600060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b50505050857f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38868686604051610e0f93929190611b3d565b60405180910390a25b505050505050565b610e28611426565b82600260008681526020019081526020016000206000019081610e4b91906120ef565b50816002600086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806002600086815260200190815260200160002060020181905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c85836040518363ffffffff1660e01b8152600401610f19929190612489565b600060405180830381600087803b158015610f3357600080fd5b505af1158015610f47573d6000803e3d6000fd5b50505050837f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38848484604051610f7f93929190611b3d565b60405180910390a250505050565b610f95611426565b610f9f60006114a4565b565b6002602052806000526040600020600091509050806000018054610fc490611cba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff090611cba565b801561103d5780601f106110125761010080835404028352916020019161103d565b820191906000526020600020905b81548152906001019060200180831161102057829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052806000526040600020600091509050806000016040518060600160405290816000820180546110cf90611cba565b80601f01602080910402602001604051908101604052809291908181526020018280546110fb90611cba565b80156111485780601f1061111d57610100808354040283529160200191611148565b820191906000526020600020905b81548152906001019060200180831161112b57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050908060030154908060040154905083565b6000600280600084815260200190815260200160002060020154146111ea57600090506112b8565b60006112a16001604060026000878152602001908152602001600020600001805461121490611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461124090611cba565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b50505050506115689092919063ffffffff16565b90506000818051906020012090508060001c925050505b919050565b60046020528060005260406000206000915090505481565b60606002600083815260200190815260200160002060000180546112f890611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461132490611cba565b80156113715780601f1061134657610100808354040283529160200191611371565b820191906000526020600020905b81548152906001019060200180831161135457829003601f168201915b50505050509050919050565b611385611426565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612524565b60405180910390fd5b6113fd816114a4565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61142e611686565b73ffffffffffffffffffffffffffffffffffffffff1661144c611073565b73ffffffffffffffffffffffffffffffffffffffff16146114a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149990612590565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606081601f8361157891906125b0565b10156115b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b090612630565b60405180910390fd5b81836115c591906125b0565b84511015611608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ff9061269c565b60405180910390fd5b6060821560008114611629576040519150600082526020820160405261167a565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611667578051835260208301925060208101905061164a565b50868552601f19601f8301166040525050505b50809150509392505050565b600033905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6116ec816116d9565b81146116f757600080fd5b50565b600081359050611709816116e3565b92915050565b600060208284031215611725576117246116cf565b5b6000611733848285016116fa565b91505092915050565b60008115159050919050565b6117518161173c565b82525050565b600060208201905061176c6000830184611748565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061179d82611772565b9050919050565b6117ad81611792565b81146117b857600080fd5b50565b6000813590506117ca816117a4565b92915050565b6000602082840312156117e6576117e56116cf565b5b60006117f4848285016117bb565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561183757808201518184015260208101905061181c565b60008484015250505050565b6000601f19601f8301169050919050565b600061185f826117fd565b6118698185611808565b9350611879818560208601611819565b61188281611843565b840191505092915050565b61189681611792565b82525050565b6118a5816116d9565b82525050565b600060608301600083015184820360008601526118c88282611854565b91505060208301516118dd602086018261188d565b5060408301516118f0604086018261189c565b508091505092915050565b6000602082019050818103600083015261191581846118ab565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61195f82611843565b810181811067ffffffffffffffff8211171561197e5761197d611927565b5b80604052505050565b60006119916116c5565b905061199d8282611956565b919050565b600067ffffffffffffffff8211156119bd576119bc611927565b5b6119c682611843565b9050602081019050919050565b82818337600083830152505050565b60006119f56119f0846119a2565b611987565b905082815260208101848484011115611a1157611a10611922565b5b611a1c8482856119d3565b509392505050565b600082601f830112611a3957611a3861191d565b5b8135611a498482602086016119e2565b91505092915050565b60008060008060808587031215611a6c57611a6b6116cf565b5b6000611a7a878288016116fa565b945050602085013567ffffffffffffffff811115611a9b57611a9a6116d4565b5b611aa787828801611a24565b9350506040611ab8878288016117bb565b9250506060611ac9878288016116fa565b91505092959194509250565b600082825260208201905092915050565b6000611af1826117fd565b611afb8185611ad5565b9350611b0b818560208601611819565b611b1481611843565b840191505092915050565b611b2881611792565b82525050565b611b37816116d9565b82525050565b60006060820190508181036000830152611b578186611ae6565b9050611b666020830185611b1f565b611b736040830184611b2e565b949350505050565b6000602082019050611b906000830184611b1f565b92915050565b60006060820190508181036000830152611bb081866118ab565b9050611bbf6020830185611b2e565b611bcc6040830184611b2e565b949350505050565b6000602082019050611be96000830184611b2e565b92915050565b60006020820190508181036000830152611c098184611ae6565b905092915050565b6000819050919050565b6000611c36611c31611c2c84611772565b611c11565b611772565b9050919050565b6000611c4882611c1b565b9050919050565b6000611c5a82611c3d565b9050919050565b611c6a81611c4f565b82525050565b6000602082019050611c856000830184611c61565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611cd257607f821691505b602082108103611ce557611ce4611c8b565b5b50919050565b600081519050611cfa816117a4565b92915050565b600060208284031215611d1657611d156116cf565b5b6000611d2484828501611ceb565b91505092915050565b611d368161173c565b8114611d4157600080fd5b50565b600081519050611d5381611d2d565b92915050565b600060208284031215611d6f57611d6e6116cf565b5b6000611d7d84828501611d44565b91505092915050565b600082825260208201905092915050565b7f4f6e6c79206163746976652076616c696461746f72732063616e20736574207260008201527f6f7574696e672064617461000000000000000000000000000000000000000000602082015250565b6000611df3602b83611d86565b9150611dfe82611d97565b604082019050919050565b60006020820190508181036000830152611e2281611de6565b9050919050565b7f596f75206861766520616c726561647920766f74656420666f7220746869732060008201527f6b65790000000000000000000000000000000000000000000000000000000000602082015250565b6000611e85602383611d86565b9150611e9082611e29565b604082019050919050565b60006020820190508181036000830152611eb481611e78565b9050919050565b7f746f6b656e496420646f6573206e6f74206d6174636820686173686564206b6560008201527f7950617274730000000000000000000000000000000000000000000000000000602082015250565b6000611f17602683611d86565b9150611f2282611ebb565b604082019050919050565b60006020820190508181036000830152611f4681611f0a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302611faf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611f72565b611fb98683611f72565b95508019841693508086168417925050509392505050565b6000611fec611fe7611fe2846116d9565b611c11565b6116d9565b9050919050565b6000819050919050565b61200683611fd1565b61201a61201282611ff3565b848454611f7f565b825550505050565b600090565b61202f612022565b61203a818484611ffd565b505050565b5b8181101561205e57612053600082612027565b600181019050612040565b5050565b601f8211156120a35761207481611f4d565b61207d84611f62565b8101602085101561208c578190505b6120a061209885611f62565b83018261203f565b50505b505050565b600082821c905092915050565b60006120c6600019846008026120a8565b1980831691505092915050565b60006120df83836120b5565b9150826002028217905092915050565b6120f8826117fd565b67ffffffffffffffff81111561211157612110611927565b5b61211b8254611cba565b612126828285612062565b600060209050601f8311600181146121595760008415612147578287015190505b61215185826120d3565b8655506121b9565b601f19841661216786611f4d565b60005b8281101561218f5784890151825560018201915060208501945060208101905061216a565b868310156121ac57848901516121a8601f8916826120b5565b8355505b6001600288020188555050505b505050505050565b6000815190506121d0816116e3565b92915050565b6000602082840312156121ec576121eb6116cf565b5b60006121fa848285016121c1565b91505092915050565b600081905092915050565b6000815461221b81611cba565b6122258186612203565b94506001821660008114612240576001811461225557612288565b60ff1983168652811515820286019350612288565b61225e85611f4d565b60005b8381101561228057815481890152600182019150602081019050612261565b838801955050505b50505092915050565b600061229d828461220e565b915081905092915050565b7f7075626b657920646f6573206e6f74206d617463682070726576696f7573207260008201527f6567697374726174696f6e730000000000000000000000000000000000000000602082015250565b6000612304602c83611d86565b915061230f826122a8565b604082019050919050565b60006020820190508181036000830152612333816122f7565b9050919050565b7f7374616b696e67436f6e747261637420646f6573206e6f74206d617463680000600082015250565b6000612370601e83611d86565b915061237b8261233a565b602082019050919050565b6000602082019050818103600083015261239f81612363565b9050919050565b7f6b65795479706520646f6573206e6f74206d6174636800000000000000000000600082015250565b60006123dc601683611d86565b91506123e7826123a6565b602082019050919050565b6000602082019050818103600083015261240b816123cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061244c826116d9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361247e5761247d612412565b5b600182019050919050565b600060408201905061249e6000830185611b2e565b6124ab6020830184611b2e565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061250e602683611d86565b9150612519826124b2565b604082019050919050565b6000602082019050818103600083015261253d81612501565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061257a602083611d86565b915061258582612544565b602082019050919050565b600060208201905081810360008301526125a98161256d565b9050919050565b60006125bb826116d9565b91506125c6836116d9565b92508282019050808211156125de576125dd612412565b5b92915050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061261a600e83611d86565b9150612625826125e4565b602082019050919050565b600060208201905081810360008301526126498161260d565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b6000612686601183611d86565b915061269182612650565b602082019050919050565b600060208201905081810360008301526126b581612679565b905091905056fea2646970667358221220e810e453728c4db244c1056ec77f87d3dcf096e755137b032e065a17382a7bb464736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063de18a50811610066578063de18a5081461025f578063ef6fd8781461028f578063f2fde38b146102bf578063ffa2e953146102db576100ea565b80638da5cb5b146101df578063b3fe5cf2146101fd578063bd4986a01461022f576100ea565b8063583cb30a116100c8578063583cb30a1461016b5780636edad78714610187578063715018a6146101a35780637bd3e3f6146101ad576100ea565b806301c6d035146100ef578063176354fd1461011f57806325c836f91461013b575b600080fd5b6101096004803603810190610104919061170f565b6102f9565b6040516101169190611757565b60405180910390f35b610139600480360381019061013491906117d0565b61046e565b005b6101556004803603810190610150919061170f565b6104f1565b60405161016291906118fb565b60405180910390f35b61018560048036038101906101809190611a52565b610610565b005b6101a1600480360381019061019c9190611a52565b610e20565b005b6101ab610f8d565b005b6101c760048036038101906101c2919061170f565b610fa1565b6040516101d693929190611b3d565b60405180910390f35b6101e7611073565b6040516101f49190611b7b565b60405180910390f35b6102176004803603810190610212919061170f565b61109c565b60405161022693929190611b96565b60405180910390f35b6102496004803603810190610244919061170f565b6111c2565b6040516102569190611b7b565b60405180910390f35b610279600480360381019061027491906117d0565b6112bd565b6040516102869190611bd4565b60405180910390f35b6102a960048036038101906102a4919061170f565b6112d5565b6040516102b69190611bef565b60405180910390f35b6102d960048036038101906102d491906117d0565b61137d565b005b6102e3611400565b6040516102f09190611c70565b60405180910390f35b6000806002600084815260200190815260200160002060405180606001604052908160008201805461032a90611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461035690611cba565b80156103a35780601f10610378576101008083540402835291602001916103a3565b820191906000526020600020905b81548152906001019060200180831161038657829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050905060008160000151511415801561042957506000816040015114155b80156104665750600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614155b915050919050565b610476611426565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc7ff7959ecbc7f4d8d4a9e6afe9dff66f0e84d0707ee870524fe965872ab6e50816040516104e69190611b7b565b60405180910390a150565b6104f961168e565b6002600083815260200190815260200160002060405180606001604052908160008201805461052790611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461055390611cba565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820154815250509050919050565b600082905060008173ffffffffffffffffffffffffffffffffffffffff16635081f66f336040518263ffffffff1660e01b81526004016106509190611b7b565b602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611d00565b90508173ffffffffffffffffffffffffffffffffffffffff166340550a1c826040518263ffffffff1660e01b81526004016106cc9190611b7b565b602060405180830381865afa1580156106e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070d9190611d59565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074390611e09565b60405180910390fd5b6003600087815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490611e9b565b60405180910390fd5b600060036000888152602001908152602001600020600301540361098257848051906020012060001c8614610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90611f2d565b60405180910390fd5b8460036000888152602001908152602001600020600001600001908161087d91906120ef565b50836003600088815260200190815260200160002060000160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260036000888152602001908152602001600020600001600201819055508173ffffffffffffffffffffffffffffffffffffffff1663dd21d6266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096391906121d6565b6003600088815260200190815260200160002060040181905550610b2c565b6003600087815260200190815260200160002060000160000180546109a690611cba565b905085511480156109ea5750600360008781526020019081526020016000206000016000016040516109d89190612291565b60405180910390208580519060200120145b610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a209061231a565b60405180910390fd5b6003600087815260200190815260200160002060000160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790612386565b60405180910390fd5b60036000878152602001908152602001600020600001600201548314610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b22906123f2565b60405180910390fd5b5b60016003600088815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600360008781526020019081526020016000206003016000815480929190610bbf90612441565b91905055503373ffffffffffffffffffffffffffffffffffffffff16867f55a9294995c030f731a7eefced80c512d4bb6826c506f230021a7320ccc1d172878787604051610c0f93929190611b3d565b60405180910390a360036000878152602001908152602001600020600401546003600088815260200190815260200160002060030154118015610c585750610c56866102f9565b155b15610e185784600260008881526020019081526020016000206000019081610c8091906120ef565b50836002600088815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260008881526020019081526020016000206002018190555060028303610d4c576000610d04876111c2565b905086600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c87856040518363ffffffff1660e01b8152600401610da9929190612489565b600060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b50505050857f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38868686604051610e0f93929190611b3d565b60405180910390a25b505050505050565b610e28611426565b82600260008681526020019081526020016000206000019081610e4b91906120ef565b50816002600086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806002600086815260200190815260200160002060020181905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c85836040518363ffffffff1660e01b8152600401610f19929190612489565b600060405180830381600087803b158015610f3357600080fd5b505af1158015610f47573d6000803e3d6000fd5b50505050837f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38848484604051610f7f93929190611b3d565b60405180910390a250505050565b610f95611426565b610f9f60006114a4565b565b6002602052806000526040600020600091509050806000018054610fc490611cba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff090611cba565b801561103d5780601f106110125761010080835404028352916020019161103d565b820191906000526020600020905b81548152906001019060200180831161102057829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052806000526040600020600091509050806000016040518060600160405290816000820180546110cf90611cba565b80601f01602080910402602001604051908101604052809291908181526020018280546110fb90611cba565b80156111485780601f1061111d57610100808354040283529160200191611148565b820191906000526020600020905b81548152906001019060200180831161112b57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050908060030154908060040154905083565b6000600280600084815260200190815260200160002060020154146111ea57600090506112b8565b60006112a16001604060026000878152602001908152602001600020600001805461121490611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461124090611cba565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b50505050506115689092919063ffffffff16565b90506000818051906020012090508060001c925050505b919050565b60046020528060005260406000206000915090505481565b60606002600083815260200190815260200160002060000180546112f890611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461132490611cba565b80156113715780601f1061134657610100808354040283529160200191611371565b820191906000526020600020905b81548152906001019060200180831161135457829003601f168201915b50505050509050919050565b611385611426565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612524565b60405180910390fd5b6113fd816114a4565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61142e611686565b73ffffffffffffffffffffffffffffffffffffffff1661144c611073565b73ffffffffffffffffffffffffffffffffffffffff16146114a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149990612590565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606081601f8361157891906125b0565b10156115b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b090612630565b60405180910390fd5b81836115c591906125b0565b84511015611608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ff9061269c565b60405180910390fd5b6060821560008114611629576040519150600082526020820160405261167a565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611667578051835260208301925060208101905061164a565b50868552601f19601f8301166040525050505b50809150509392505050565b600033905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6116ec816116d9565b81146116f757600080fd5b50565b600081359050611709816116e3565b92915050565b600060208284031215611725576117246116cf565b5b6000611733848285016116fa565b91505092915050565b60008115159050919050565b6117518161173c565b82525050565b600060208201905061176c6000830184611748565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061179d82611772565b9050919050565b6117ad81611792565b81146117b857600080fd5b50565b6000813590506117ca816117a4565b92915050565b6000602082840312156117e6576117e56116cf565b5b60006117f4848285016117bb565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561183757808201518184015260208101905061181c565b60008484015250505050565b6000601f19601f8301169050919050565b600061185f826117fd565b6118698185611808565b9350611879818560208601611819565b61188281611843565b840191505092915050565b61189681611792565b82525050565b6118a5816116d9565b82525050565b600060608301600083015184820360008601526118c88282611854565b91505060208301516118dd602086018261188d565b5060408301516118f0604086018261189c565b508091505092915050565b6000602082019050818103600083015261191581846118ab565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61195f82611843565b810181811067ffffffffffffffff8211171561197e5761197d611927565b5b80604052505050565b60006119916116c5565b905061199d8282611956565b919050565b600067ffffffffffffffff8211156119bd576119bc611927565b5b6119c682611843565b9050602081019050919050565b82818337600083830152505050565b60006119f56119f0846119a2565b611987565b905082815260208101848484011115611a1157611a10611922565b5b611a1c8482856119d3565b509392505050565b600082601f830112611a3957611a3861191d565b5b8135611a498482602086016119e2565b91505092915050565b60008060008060808587031215611a6c57611a6b6116cf565b5b6000611a7a878288016116fa565b945050602085013567ffffffffffffffff811115611a9b57611a9a6116d4565b5b611aa787828801611a24565b9350506040611ab8878288016117bb565b9250506060611ac9878288016116fa565b91505092959194509250565b600082825260208201905092915050565b6000611af1826117fd565b611afb8185611ad5565b9350611b0b818560208601611819565b611b1481611843565b840191505092915050565b611b2881611792565b82525050565b611b37816116d9565b82525050565b60006060820190508181036000830152611b578186611ae6565b9050611b666020830185611b1f565b611b736040830184611b2e565b949350505050565b6000602082019050611b906000830184611b1f565b92915050565b60006060820190508181036000830152611bb081866118ab565b9050611bbf6020830185611b2e565b611bcc6040830184611b2e565b949350505050565b6000602082019050611be96000830184611b2e565b92915050565b60006020820190508181036000830152611c098184611ae6565b905092915050565b6000819050919050565b6000611c36611c31611c2c84611772565b611c11565b611772565b9050919050565b6000611c4882611c1b565b9050919050565b6000611c5a82611c3d565b9050919050565b611c6a81611c4f565b82525050565b6000602082019050611c856000830184611c61565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611cd257607f821691505b602082108103611ce557611ce4611c8b565b5b50919050565b600081519050611cfa816117a4565b92915050565b600060208284031215611d1657611d156116cf565b5b6000611d2484828501611ceb565b91505092915050565b611d368161173c565b8114611d4157600080fd5b50565b600081519050611d5381611d2d565b92915050565b600060208284031215611d6f57611d6e6116cf565b5b6000611d7d84828501611d44565b91505092915050565b600082825260208201905092915050565b7f4f6e6c79206163746976652076616c696461746f72732063616e20736574207260008201527f6f7574696e672064617461000000000000000000000000000000000000000000602082015250565b6000611df3602b83611d86565b9150611dfe82611d97565b604082019050919050565b60006020820190508181036000830152611e2281611de6565b9050919050565b7f596f75206861766520616c726561647920766f74656420666f7220746869732060008201527f6b65790000000000000000000000000000000000000000000000000000000000602082015250565b6000611e85602383611d86565b9150611e9082611e29565b604082019050919050565b60006020820190508181036000830152611eb481611e78565b9050919050565b7f746f6b656e496420646f6573206e6f74206d6174636820686173686564206b6560008201527f7950617274730000000000000000000000000000000000000000000000000000602082015250565b6000611f17602683611d86565b9150611f2282611ebb565b604082019050919050565b60006020820190508181036000830152611f4681611f0a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302611faf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611f72565b611fb98683611f72565b95508019841693508086168417925050509392505050565b6000611fec611fe7611fe2846116d9565b611c11565b6116d9565b9050919050565b6000819050919050565b61200683611fd1565b61201a61201282611ff3565b848454611f7f565b825550505050565b600090565b61202f612022565b61203a818484611ffd565b505050565b5b8181101561205e57612053600082612027565b600181019050612040565b5050565b601f8211156120a35761207481611f4d565b61207d84611f62565b8101602085101561208c578190505b6120a061209885611f62565b83018261203f565b50505b505050565b600082821c905092915050565b60006120c6600019846008026120a8565b1980831691505092915050565b60006120df83836120b5565b9150826002028217905092915050565b6120f8826117fd565b67ffffffffffffffff81111561211157612110611927565b5b61211b8254611cba565b612126828285612062565b600060209050601f8311600181146121595760008415612147578287015190505b61215185826120d3565b8655506121b9565b601f19841661216786611f4d565b60005b8281101561218f5784890151825560018201915060208501945060208101905061216a565b868310156121ac57848901516121a8601f8916826120b5565b8355505b6001600288020188555050505b505050505050565b6000815190506121d0816116e3565b92915050565b6000602082840312156121ec576121eb6116cf565b5b60006121fa848285016121c1565b91505092915050565b600081905092915050565b6000815461221b81611cba565b6122258186612203565b94506001821660008114612240576001811461225557612288565b60ff1983168652811515820286019350612288565b61225e85611f4d565b60005b8381101561228057815481890152600182019150602081019050612261565b838801955050505b50505092915050565b600061229d828461220e565b915081905092915050565b7f7075626b657920646f6573206e6f74206d617463682070726576696f7573207260008201527f6567697374726174696f6e730000000000000000000000000000000000000000602082015250565b6000612304602c83611d86565b915061230f826122a8565b604082019050919050565b60006020820190508181036000830152612333816122f7565b9050919050565b7f7374616b696e67436f6e747261637420646f6573206e6f74206d617463680000600082015250565b6000612370601e83611d86565b915061237b8261233a565b602082019050919050565b6000602082019050818103600083015261239f81612363565b9050919050565b7f6b65795479706520646f6573206e6f74206d6174636800000000000000000000600082015250565b60006123dc601683611d86565b91506123e7826123a6565b602082019050919050565b6000602082019050818103600083015261240b816123cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061244c826116d9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361247e5761247d612412565b5b600182019050919050565b600060408201905061249e6000830185611b2e565b6124ab6020830184611b2e565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061250e602683611d86565b9150612519826124b2565b604082019050919050565b6000602082019050818103600083015261253d81612501565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061257a602083611d86565b915061258582612544565b602082019050919050565b600060208201905081810360008301526125a98161256d565b9050919050565b60006125bb826116d9565b91506125c6836116d9565b92508282019050808211156125de576125dd612412565b5b92915050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061261a600e83611d86565b9150612625826125e4565b602082019050919050565b600060208201905081810360008301526126498161260d565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b6000612686601183611d86565b915061269182612650565b602082019050919050565b600060208201905081810360008301526126b581612679565b905091905056fea2646970667358221220e810e453728c4db244c1056ec77f87d3dcf096e755137b032e065a17382a7bb464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"PkpNftAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"pubkey","type":"bytes"},{"indexed":false,"internalType":"address","name":"stakingContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PubkeyRoutingDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"pubkey","type":"bytes"},{"indexed":false,"internalType":"address","name":"stakingContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PubkeyRoutingDataVote","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRoutingData","outputs":[{"components":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"internalType":"struct PubkeyRouter.PubkeyRoutingData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isRouted","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeyRegistrations","outputs":[{"components":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"internalType":"struct PubkeyRouter.PubkeyRoutingData","name":"routingData","type":"tuple"},{"internalType":"uint256","name":"nodeVoteCount","type":"uint256"},{"internalType":"uint256","name":"nodeVoteThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"setRoutingData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"voteForRoutingData","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/RateLimitNFT.json b/deployments/lit_175177/RateLimitNFT.json deleted file mode 100644 index 00e2429..0000000 --- a/deployments/lit_175177/RateLimitNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/RateLimitNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Rate Limit NFT\\n///\\n/// @dev This is the contract for the Rate Limit NFTs\\n/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit\\n/// And how it works, is that you can buy X requestsPerKilosecond over a period of time\\n/// 1 requestsPerKilosecond = 0.001 requests per second and\\n/// 1000 requestsPerKilosecond = 1 request per second\\ncontract RateLimitNFT is\\n ERC721(\\\"Rate Limit Increases on Lit Protocol\\\", \\\"RLI\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using Strings for uint256;\\n /* ========== STATE VARIABLES ========== */\\n\\n address public freeMintSigner;\\n uint256 public additionalRequestsPerKilosecondCost;\\n uint256 public tokenIdCounter;\\n uint256 public defaultRateLimitWindowSeconds = 60 * 60; // 60 mins\\n uint256 public RLIHolderRateLimitWindowSeconds = 5 * 60; // 5 mins\\n uint256 public freeRequestsPerRateLimitWindow = 10;\\n\\n mapping(uint256 => RateLimit) public capacity;\\n mapping(bytes32 => bool) public redeemedFreeMints;\\n\\n struct RateLimit {\\n uint256 requestsPerKilosecond;\\n uint256 expiresAt;\\n }\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n // make sure the msgHash matches the tokenId\\n // if these don't match, the user could use any old signature\\n // to mint any number of PKPs\\n // and this would be vulnerable to replay attacks\\n // FIXME this needs the whole \\\"ethereum signed message: \\\\27\\\" thingy prepended to actually work\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // make sure it hasn't already been redeemed\\n require(\\n !redeemedFreeMints[msgHash],\\n \\\"This freeMint has already been redeemed. How embarassing.\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function calculateCost(\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n require(\\n requestsPerKilosecond > 0,\\n \\\"The requestsPerKilosecond must be greater than 0\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n\\n // calculate the cost\\n uint256 cost = (requestsPerKilosecond *\\n durationInSeconds *\\n additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return cost;\\n }\\n\\n function calculateRequestsPerKilosecond(\\n uint256 payingAmount,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n // console.log(\\\"durationInSeconds: \\\");\\n // console.log(durationInSeconds);\\n\\n // calculate the cost\\n uint256 requestsPerKilosecond = payingAmount /\\n ((durationInSeconds * additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return requestsPerKilosecond;\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit Protocol Rate Limit Increase\\\", \\\"description\\\": \\\"This NFT entitles the holder to a rate limit increase on the Lit Protocol Network\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"display_type\\\": \\\"date\\\", \\\"trait_type\\\": \\\"Expiration Date\\\", \\\"value\\\": ',\\n capacity[tokenId].expiresAt.toString(),\\n '}, {\\\"display_type\\\": \\\"number\\\", \\\"trait_type\\\": \\\"Millirequests Per Second\\\", \\\"value\\\": ',\\n capacity[tokenId].requestsPerKilosecond.toString(),\\n \\\"}]}\\\"\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n\\n function isExpired(uint256 tokenId) public view returns (bool) {\\n return capacity[tokenId].expiresAt <= block.timestamp;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function.\\n function mint(uint256 expiresAt) public payable returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n uint256 requestsPerKilosecond = calculateRequestsPerKilosecond(\\n msg.value,\\n expiresAt\\n );\\n\\n // sanity check\\n uint256 cost = calculateCost(requestsPerKilosecond, expiresAt);\\n\\n require(\\n msg.value > 0 && msg.value >= cost,\\n \\\"You must send the cost of this rate limit increase. To check the cost, use the calculateCost function.\\\"\\n );\\n require(cost > 0, \\\"The cost must be greater than 0\\\");\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function freeMint(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(expiresAt, requestsPerKilosecond, msgHash, v, r, s);\\n redeemedFreeMints[msgHash] = true;\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n uint256 tokenId,\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) internal {\\n _safeMint(msg.sender, tokenId);\\n capacity[tokenId] = RateLimit(requestsPerKilosecond, expiresAt);\\n }\\n\\n function setAdditionalRequestsPerKilosecondCost(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n ) public onlyOwner {\\n additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost;\\n emit AdditionalRequestsPerKilosecondCostSet(\\n newAdditionalRequestsPerKilosecondCost\\n );\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n function setRateLimitWindowSeconds(\\n uint256 newRateLimitWindowSeconds\\n ) public onlyOwner {\\n defaultRateLimitWindowSeconds = newRateLimitWindowSeconds;\\n emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds);\\n }\\n\\n function setRLIHolderRateLimitWindowSeconds(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n ) public onlyOwner {\\n RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds;\\n emit RLIHolderRateLimitWindowSecondsSet(\\n newRLIHolderRateLimitWindowSeconds\\n );\\n }\\n\\n function setFreeRequestsPerRateLimitWindow(\\n uint256 newFreeRequestsPerRateLimitWindow\\n ) public onlyOwner {\\n freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow;\\n emit FreeRequestsPerRateLimitWindowSet(\\n newFreeRequestsPerRateLimitWindow\\n );\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event AdditionalRequestsPerKilosecondCostSet(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n );\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds);\\n event RLIHolderRateLimitWindowSecondsSet(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n );\\n event FreeRequestsPerRateLimitWindowSet(\\n uint256 newFreeRequestsPerRateLimitWindow\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x393bf9aF30D0a28A98fF237184f7773474B0A1BF","bytecode":"0x6080604052610e10600f5561012c601055600a6011553480156200002257600080fd5b50604051806060016040528060248152602001620055f8602491396040518060400160405280600381526020017f524c490000000000000000000000000000000000000000000000000000000000815250816000908162000084919062000419565b50806001908162000096919062000419565b505050620000b9620000ad620000d160201b60201c565b620000d960201b60201c565b6001600b81905550620f4240600d8190555062000500565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200022157607f821691505b602082108103620002375762000236620001d9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000262565b620002ad868362000262565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002fa620002f4620002ee84620002c5565b620002cf565b620002c5565b9050919050565b6000819050919050565b6200031683620002d9565b6200032e620003258262000301565b8484546200026f565b825550505050565b600090565b6200034562000336565b620003528184846200030b565b505050565b5b818110156200037a576200036e6000826200033b565b60018101905062000358565b5050565b601f821115620003c95762000393816200023d565b6200039e8462000252565b81016020851015620003ae578190505b620003c6620003bd8562000252565b83018262000357565b50505b505050565b600082821c905092915050565b6000620003ee60001984600802620003ce565b1980831691505092915050565b6000620004098383620003db565b9150826002028217905092915050565b62000424826200019f565b67ffffffffffffffff81111562000440576200043f620001aa565b5b6200044c825462000208565b620004598282856200037e565b600060209050601f8311600181146200049157600084156200047c578287015190505b620004888582620003fb565b865550620004f8565b601f198416620004a1866200023d565b60005b82811015620004cb57848901518255600182019150602085019450602081019050620004a4565b86831015620004eb5784890151620004e7601f891682620003db565b8355505b6001600288020188555050505b505050505050565b6150e880620005106000396000f3fe6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c6343000811003352617465204c696d697420496e63726561736573206f6e204c69742050726f746f636f6c","deployedBytecode":"0x6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"AdditionalRequestsPerKilosecondCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"FreeRequestsPerRateLimitWindowSet","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":false,"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"RLIHolderRateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"RateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"RLIHolderRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalRequestsPerKilosecondCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payingAmount","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateRequestsPerKilosecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capacity","outputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeRequestsPerRateLimitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"isExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"redeemedFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"setAdditionalRequestsPerKilosecondCost","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"setFreeRequestsPerRateLimitWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"setRLIHolderRateLimitWindowSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"setRateLimitWindowSeconds","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/SoloNetPKP.json b/deployments/lit_175177/SoloNetPKP.json deleted file mode 100644 index 8bab36e..0000000 --- a/deployments/lit_175177/SoloNetPKP.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x0B06059b15fFDE432C33a9379104Ea8DE2a9C2F8","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000559565b508060019081620000a1919062000559565b505050620000c4620000b86200013c60201b60201c565b6200014460201b60201c565b6001600b81905550655af3107a4000600e8190555033600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001353360116200020a60201b6200240d1790919060201c565b5062000640565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006200023a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200024260201b60201c565b905092915050565b6000620002568383620002bc60201b60201c565b620002b1578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050620002b6565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200036157607f821691505b60208210810362000377576200037662000319565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003a2565b620003ed8683620003a2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200043a620004346200042e8462000405565b6200040f565b62000405565b9050919050565b6000819050919050565b620004568362000419565b6200046e620004658262000441565b848454620003af565b825550505050565b600090565b6200048562000476565b620004928184846200044b565b505050565b5b81811015620004ba57620004ae6000826200047b565b60018101905062000498565b5050565b601f8211156200050957620004d3816200037d565b620004de8462000392565b81016020851015620004ee578190505b62000506620004fd8562000392565b83018262000497565b50505b505050565b600082821c905092915050565b60006200052e600019846008026200050e565b1980831691505092915050565b60006200054983836200051b565b9150826002028217905092915050565b6200056482620002df565b67ffffffffffffffff81111562000580576200057f620002ea565b5b6200058c825462000348565b62000599828285620004be565b600060209050601f831160018114620005d15760008415620005bc578287015190505b620005c885826200053b565b86555062000638565b601f198416620005e1866200037d565b60005b828110156200060b57848901518255600182019150602085019450602081019050620005e4565b868310156200062b578489015162000627601f8916826200051b565b8355505b6001600288020188555050505b505050505050565b61598b80620006506000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122080cad9d7cc14690992b06395c8008178c79f26b0a2a260deb1a280e2b6d649e564736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122080cad9d7cc14690992b06395c8008178c79f26b0a2a260deb1a280e2b6d649e564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterPermitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRevoked","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingAddress","type":"address"}],"name":"StakingAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"_getTokenIdToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"addPermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"removePermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/SoloNetPKPHelper.json b/deployments/lit_175177/SoloNetPKPHelper.json deleted file mode 100644 index 627034c..0000000 --- a/deployments/lit_175177/SoloNetPKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { SoloNetPKP } from \\\"./SoloNetPKP.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/// @title PKP Helper Contract\\n///\\n/// @dev This is the contract that helps minting PKPs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n SoloNetPKP public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = SoloNetPKP(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintAndAddAuthMethods(\\n bytes memory pubkey,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintAndAddAuthMethodsWithTypes(\\n pubkey,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintAndAddAuthMethodsWithTypes(\\n bytes memory pubkey,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpNFT.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = SoloNetPKP(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x116532bD457c74f8de2d450cf62F0C6FF1C58CF4","bytecode":"0x60806040523480156200001157600080fd5b506040516200254d3803806200254d833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b6122df806200026e6000396000f3fe6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220fe76437deb86295c7e3dcef45d4697442e812480a8078c5ca0787a3b750cf99464736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220fe76437deb86295c7e3dcef45d4697442e812480a8078c5ca0787a3b750cf99464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract SoloNetPKP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/lit_175177/Staking.json b/deployments/lit_175177/Staking.json deleted file mode 100644 index 93b4722..0000000 --- a/deployments/lit_175177/Staking.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x2Be79261f706312F1F5855059f57Fd298F8e0646","bytecode":"0x60806040526000600160156101000a81548160ff021916908360048111156200002d576200002c6200039f565b5b02179055503480156200003f57600080fd5b5060405162005e0438038062005e04833981810160405281019062000065919062000438565b60016000819055506000600160006101000a81548160ff021916908315150217905550620000a86200009c620002d460201b60201c565b620002dc60201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060a001604052806050815260200160018152602001600143620001119190620004a3565b8152602001600081526020016050815250600360008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506014600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ef91906200051c565b600a620001fd9190620006a2565b62000209919062000722565b600881905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a391906200051c565b600a620002b19190620006a2565b6001620002bf91906200075a565b6009819055506000600b8190555050620007a5565b600033905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040082620003d3565b9050919050565b6200041281620003f3565b81146200041e57600080fd5b50565b600081519050620004328162000407565b92915050565b600060208284031215620004515762000450620003ce565b5b6000620004618482850162000421565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004b0826200046a565b9150620004bd836200046a565b9250828201905080821115620004d857620004d762000474565b5b92915050565b600060ff82169050919050565b620004f681620004de565b81146200050257600080fd5b50565b6000815190506200051681620004eb565b92915050565b600060208284031215620005355762000534620003ce565b5b6000620005458482850162000505565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115620005ad5780860481111562000585576200058462000474565b5b6001851615620005955780820291505b8081029050620005a5856200054e565b945062000565565b94509492505050565b600082620005c857600190506200069b565b81620005d857600090506200069b565b8160018114620005f15760028114620005fc5762000632565b60019150506200069b565b60ff84111562000611576200061062000474565b5b8360020a9150848211156200062b576200062a62000474565b5b506200069b565b5060208310610133831016604e8410600b84101617156200066c5782820a90508381111562000666576200066562000474565b5b6200069b565b6200067b84848460016200055b565b9250905081840481111562000695576200069462000474565b5b81810290505b9392505050565b6000620006af826200046a565b9150620006bc83620004de565b9250620006eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620005b6565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006200072f826200046a565b91506200073c836200046a565b9250826200074f576200074e620006f3565b5b828204905092915050565b600062000767826200046a565b915062000774836200046a565b925082820262000784816200046a565b915082820484148315176200079e576200079d62000474565b5b5092915050565b61564f80620007b56000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613c4d565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613cd0565b610a75565b6040516103609190613c4d565b60405180910390f35b610383600480360381019061037e9190613cd0565b610ac1565b005b61039f600480360381019061039a9190613d29565b610b44565b005b6103bb60048036038101906103b69190613d29565b610b90565b005b6103d760048036038101906103d29190613d29565b610bd9565b005b6103f360048036038101906103ee9190613dda565b610eea565b005b6103fd61143f565b005b610407611888565b005b610423600480360381019061041e9190613e8c565b611a68565b005b61043f600480360381019061043a9190613cd0565b611ad4565b60405161044c9190613ed4565b60405180910390f35b61046f600480360381019061046a9190613d29565b611af1565b005b61048b60048036038101906104869190613eef565b611b3a565b6040516104989190613c4d565b60405180910390f35b6104bb60048036038101906104b69190613dda565b611b65565b005b6104d760048036038101906104d29190613cd0565b611db7565b6040516104e49190613f3e565b60405180910390f35b61050760048036038101906105029190613cd0565b611dea565b6040516105149190613ed4565b60405180910390f35b61053760048036038101906105329190613d29565b611e0a565b005b610541611e56565b60405161054e9190613ed4565b60405180910390f35b610571600480360381019061056c9190613cd0565b611e6d565b60405161057e9190613c4d565b60405180910390f35b6105a1600480360381019061059c9190613f59565b611eb9565b6040516105af929190613fac565b60405180910390f35b6105c0611f71565b005b6105ca611f85565b6040516105d79190614034565b60405180910390f35b6105fa60048036038101906105f59190613cd0565b611fab565b005b610604612084565b6040516106119190613c4d565b60405180910390f35b610634600480360381019061062f9190613cd0565b61208a565b6040516106419190613ed4565b60405180910390f35b61065261210b565b60405161065f919061410d565b60405180910390f35b610682600480360381019061067d9190614194565b6121f9565b005b61069e60048036038101906106999190614208565b6127eb565b005b6106a8612999565b6040516106b59190613ed4565b60405180910390f35b6106c66129d7565b6040516106d39190613f3e565b60405180910390f35b6106e46129ff565b6040516106f5959493929190614248565b60405180910390f35b61071860048036038101906107139190613cd0565b612a23565b005b610722612aa6565b60405161072f9190613ed4565b60405180910390f35b610752600480360381019061074d9190613d29565b612ae3565b005b61075c612ce1565b005b610766612e9b565b005b610770612f08565b60405161077d9190613f3e565b60405180910390f35b61078e612f2e565b60405161079b9190613c4d565b60405180910390f35b6107be60048036038101906107b9919061429b565b612f34565b005b6107c8612f5c565b005b6107d26131f2565b005b6107dc6133e6565b6040516107e991906143b4565b60405180910390f35b6107fa6133f9565b604051610807919061410d565b60405180910390f35b6108186134e7565b6040516108259190613c4d565b60405180910390f35b61084860048036038101906108439190613d29565b61352b565b005b610852613574565b005b61085c6135c9565b6040516108699190613c4d565b60405180910390f35b61087a6135cf565b6040516108879190613ed4565b60405180910390f35b6108aa60048036038101906108a59190613cd0565b61369a565b005b6108b461371d565b6040516108c19190613ed4565b60405180910390f35b6108e460048036038101906108df9190613cd0565b61375b565b6040516108f89897969594939291906143ed565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610946906144ee565b60405180910390fd5b600060048111156109635761096261433d565b5b600160159054906101000a900460ff1660048111156109855761098461433d565b5b14806109c45750600360048111156109a05761099f61433d565b5b600160159054906101000a900460ff1660048111156109c2576109c161433d565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614580565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a2761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b91906143b4565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac96137ff565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b399190613f3e565b60405180910390a150565b610b4c6137ff565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613c4d565b60405180910390a150565b610b986137ff565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613c4d565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c15906145ec565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6090614658565b60405180910390fd5b60001515610c8133600c61387d90919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90614736565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f906147a2565b60405180910390fd5b80600a54610d5691906147f1565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa91906147f1565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610e4d929190614825565b6020604051808303816000875af1158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e90919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610ed79190613c4d565b60405180910390a2600160008190555050565b600260005403610f2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f26906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610fc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fba90614919565b60405180910390fd5b60006004811115610fd757610fd661433d565b5b600160159054906101000a900460ff166004811115610ff957610ff861433d565b5b14806110385750600360048111156110145761101361433d565b5b600160159054906101000a900460ff1660048111156110365761103561433d565b5b145b8061107557506004808111156110515761105061433d565b5b600160159054906101000a900460ff1660048111156110735761107261433d565b5b145b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ab906149ab565b60405180910390fd5b600015156110cc33601061387d90919063ffffffff16565b15151461110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590614a3d565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea33600e6138ad90919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147e906144ee565b60405180910390fd5b6002600481111561149b5761149a61433d565b5b600160159054906101000a900460ff1660048111156114bd576114bc61433d565b5b146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f490614acf565b60405180910390fd5b600115156115096135cf565b15151461154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154290614b61565b60405180910390fd5b6000611557600c6138dd565b905060005b818110156116df57600061157a82600c6138f290919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190614bba565b600a6116199190614d1a565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116699190614d65565b6116739190614dd6565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116c49190614e07565b925050819055505080806116d790614e3b565b91505061155c565b505b60006116ed600c6138dd565b11156117215761171b61170b6000600c6138f290919063ffffffff16565b600c61390c90919063ffffffff16565b506116e1565b61172b600e6138dd565b905060005b818110156117de5761175f61174f82600e6138f290919063ffffffff16565b600c6138ad90919063ffffffff16565b5060006014600061177a84600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806117d690614e3b565b915050611730565b50600360010160008154809291906117f590614e3b565b91905055506003600001544361180b9190614e07565b6003600201819055506000600160156101000a81548160ff0219169083600481111561183a5761183961433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff1660405161187d91906143b4565b60405180910390a150565b6002600054036118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000811115611a5d576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016119ca929190614825565b6020604051808303816000875af11580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611a549190613c4d565b60405180910390a25b506001600081905550565b611a706137ff565b80600160156101000a81548160ff02191690836004811115611a9557611a9461433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611ac991906143b4565b60405180910390a150565b6000611aea82600c61387d90919063ffffffff16565b9050919050565b611af96137ff565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611b2f9190613c4d565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611e126137ff565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611e4b9190613c4d565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611f796137ff565b611f83600061393c565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe7906145ec565b60405180910390fd5b60026000819055506120006137ff565b61201481600e61390c90919063ffffffff16565b506120298160106138ad90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e9760006040516120719190614ebe565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120ec6134e7565b816000015410612100576001915050612106565b60009150505b919050565b60606000612119600c6138dd565b67ffffffffffffffff81111561213257612131614ed9565b5b6040519080825280602002602001820160405280156121605781602001602082028036833780820191505090505b509050600061216f600c6138dd565b905060005b818110156121f05761219081600c6138f290919063ffffffff16565b8382815181106121a3576121a2614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806121e890614e3b565b915050612174565b50819250505090565b60026000540361223e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612235906145ec565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fa9565b60405180910390fd5b61232d81600e61387d90919063ffffffff16565b61236c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236390615061565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c906150f3565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008154809291906124be90614e3b565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061258585600e61387d90919063ffffffff16565b801561259657506125958561208a565b5b15612774576125af85600e61390c90919063ffffffff16565b506125c48560106138ad90919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546126199190614d65565b6126239190614dd6565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461267791906147f1565b9250508190555080600a600082825461269091906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016126f29190613c4d565b600060405180830381600087803b15801561270c57600080fd5b505af1158015612720573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e978260405161276a9190613c4d565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa86866040516127d4929190615171565b60405180910390a450600160008190555050505050565b600260005403612830576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612827906145ec565b60405180910390fd5b60026000819055506128406137ff565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461289291906147f1565b9250508190555080600a60008282546128ab91906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161290d9190613c4d565b600060405180830381600087803b15801561292757600080fd5b505af115801561293b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516129859190613c4d565b60405180910390a260016000819055505050565b6000600160048111156129af576129ae61433d565b5b600160159054906101000a900460ff1660048111156129d1576129d061433d565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612a2b6137ff565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a607581604051612a9b9190613f3e565b60405180910390a150565b6000806004811115612abb57612aba61433d565b5b600160159054906101000a900460ff166004811115612add57612adc61433d565b5b14905090565b600260005403612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f906145ec565b60405180910390fd5b600260008190555060008111612b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6a906151e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401612bd293929190615201565b6020604051808303816000875af1158015612bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c15919061487a565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612c689190614e07565b9250508190555080600a6000828254612c819190614e07565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612cce9190613c4d565b60405180910390a2600160008190555050565b600260005403612d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1d906145ec565b60405180910390fd5b600260008190555060006004811115612d4257612d4161433d565b5b600160159054906101000a900460ff166004811115612d6457612d6361433d565b5b1480612da3575060036004811115612d7f57612d7e61433d565b5b600160159054906101000a900460ff166004811115612da157612da061433d565b5b145b80612de05750600480811115612dbc57612dbb61433d565b5b600160159054906101000a900460ff166004811115612dde57612ddd61433d565b5b145b612e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e16906152aa565b60405180910390fd5b612e3333600e61387d90919063ffffffff16565b15612e4e57612e4c33600e61390c90919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612ea36137ff565b6004600160156101000a81548160ff02191690836004811115612ec957612ec861433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612efe91906143b4565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612f3c6139ff565b612f4587612ae3565b612f53868686868686610eea565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612fd457612fd361433d565b5b600160159054906101000a900460ff166004811115612ff657612ff561433d565b5b14806130355750600260048111156130115761301061433d565b5b600160159054906101000a900460ff1660048111156130335761303261433d565b5b145b613074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306b9061533c565b60405180910390fd5b6001600360010154146130d55761309581600e61387d90919063ffffffff16565b6130d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cb906153ce565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a26131786135cf565b156131ef576002600160156101000a81548160ff021916908360048111156131a3576131a261433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516131e691906143b4565b60405180910390a15b50565b6003600401546003600201546132089190614e07565b43101561324a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613241906144ee565b60405180910390fd5b6001600481111561325e5761325d61433d565b5b600160159054906101000a900460ff1660048111156132805761327f61433d565b5b146132c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132b790615460565b60405180910390fd5b60006132cc600e6138dd565b905060005b81811015613357576000601460006132f384600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061334f90614e3b565b9150506132d1565b5060038001600081548092919061336d90614e3b565b91905055506003600160156101000a81548160ff021916908360048111156133985761339761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516133db91906143b4565b60405180910390a150565b600160159054906101000a900460ff1681565b60606000613407600e6138dd565b67ffffffffffffffff8111156134205761341f614ed9565b5b60405190808252806020026020018201604052801561344e5781602001602082028036833780820191505090505b509050600061345d600e6138dd565b905060005b818110156134de5761347e81600e6138f290919063ffffffff16565b83828151811061349157613490614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806134d690614e3b565b915050613462565b50819250505090565b600060026134f5600c6138dd565b116135035760019050613528565b60036002613511600c6138dd565b61351b9190614d65565b6135259190614dd6565b90505b90565b6135336137ff565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a5816040516135699190613c4d565b60405180910390a150565b6135bf601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6135c7611888565b565b60095481565b6000806000905060006135e2600e6138dd565b905060005b81811015613676576014600061360783600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561366357828061365f90614e3b565b9350505b808061366e90614e3b565b9150506135e7565b5061367f6134e7565b821061369057600192505050613697565b6000925050505b90565b6136a26137ff565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613711576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613708906154f2565b60405180910390fd5b61371a8161393c565b50565b6000600360048111156137335761373261433d565b5b600160159054906101000a900460ff1660048111156137555761375461433d565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b613807613a49565b73ffffffffffffffffffffffffffffffffffffffff166138256129d7565b73ffffffffffffffffffffffffffffffffffffffff161461387b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138729061555e565b60405180910390fd5b565b60006138a5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a51565b905092915050565b60006138d5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a74565b905092915050565b60006138eb82600001613ae4565b9050919050565b60006139018360000183613af5565b60001c905092915050565b6000613934836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b20565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a07611e56565b15613a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a3e906155ca565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613a808383613a51565b613ad9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613ade565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613b0d57613b0c614f08565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613c28576000600182613b5291906147f1565b9050600060018660000180549050613b6a91906147f1565b9050818114613bd9576000866000018281548110613b8b57613b8a614f08565b5b9060005260206000200154905080876000018481548110613baf57613bae614f08565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613bed57613bec6155ea565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613c2e565b60009150505b92915050565b6000819050919050565b613c4781613c34565b82525050565b6000602082019050613c626000830184613c3e565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c9d82613c72565b9050919050565b613cad81613c92565b8114613cb857600080fd5b50565b600081359050613cca81613ca4565b92915050565b600060208284031215613ce657613ce5613c68565b5b6000613cf484828501613cbb565b91505092915050565b613d0681613c34565b8114613d1157600080fd5b50565b600081359050613d2381613cfd565b92915050565b600060208284031215613d3f57613d3e613c68565b5b6000613d4d84828501613d14565b91505092915050565b600063ffffffff82169050919050565b613d6f81613d56565b8114613d7a57600080fd5b50565b600081359050613d8c81613d66565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613db781613d92565b8114613dc257600080fd5b50565b600081359050613dd481613dae565b92915050565b60008060008060008060c08789031215613df757613df6613c68565b5b6000613e0589828a01613d7d565b9650506020613e1689828a01613dc5565b9550506040613e2789828a01613d7d565b9450506060613e3889828a01613cbb565b9350506080613e4989828a01613d14565b92505060a0613e5a89828a01613d14565b9150509295509295509295565b60058110613e7457600080fd5b50565b600081359050613e8681613e67565b92915050565b600060208284031215613ea257613ea1613c68565b5b6000613eb084828501613e77565b91505092915050565b60008115159050919050565b613ece81613eb9565b82525050565b6000602082019050613ee96000830184613ec5565b92915050565b60008060408385031215613f0657613f05613c68565b5b6000613f1485828601613d14565b9250506020613f2585828601613cbb565b9150509250929050565b613f3881613c92565b82525050565b6000602082019050613f536000830184613f2f565b92915050565b600080600060608486031215613f7257613f71613c68565b5b6000613f8086828701613d14565b9350506020613f9186828701613cbb565b9250506040613fa286828701613cbb565b9150509250925092565b6000604082019050613fc16000830185613c3e565b613fce6020830184613ec5565b9392505050565b6000819050919050565b6000613ffa613ff5613ff084613c72565b613fd5565b613c72565b9050919050565b600061400c82613fdf565b9050919050565b600061401e82614001565b9050919050565b61402e81614013565b82525050565b60006020820190506140496000830184614025565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61408481613c92565b82525050565b6000614096838361407b565b60208301905092915050565b6000602082019050919050565b60006140ba8261404f565b6140c4818561405a565b93506140cf8361406b565b8060005b838110156141005781516140e7888261408a565b97506140f2836140a2565b9250506001810190506140d3565b5085935050505092915050565b6000602082019050818103600083015261412781846140af565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141545761415361412f565b5b8235905067ffffffffffffffff81111561417157614170614134565b5b60208301915083600182028301111561418d5761418c614139565b5b9250929050565b600080600080606085870312156141ae576141ad613c68565b5b60006141bc87828801613cbb565b94505060206141cd87828801613d14565b935050604085013567ffffffffffffffff8111156141ee576141ed613c6d565b5b6141fa8782880161413e565b925092505092959194509250565b6000806040838503121561421f5761421e613c68565b5b600061422d85828601613cbb565b925050602061423e85828601613d14565b9150509250929050565b600060a08201905061425d6000830188613c3e565b61426a6020830187613c3e565b6142776040830186613c3e565b6142846060830185613c3e565b6142916080830184613c3e565b9695505050505050565b600080600080600080600060e0888a0312156142ba576142b9613c68565b5b60006142c88a828b01613d14565b97505060206142d98a828b01613d7d565b96505060406142ea8a828b01613dc5565b95505060606142fb8a828b01613d7d565b945050608061430c8a828b01613cbb565b93505060a061431d8a828b01613d14565b92505060c061432e8a828b01613d14565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061437d5761437c61433d565b5b50565b600081905061438e8261436c565b919050565b600061439e82614380565b9050919050565b6143ae81614393565b82525050565b60006020820190506143c960008301846143a5565b92915050565b6143d881613d56565b82525050565b6143e781613d92565b82525050565b600061010082019050614403600083018b6143cf565b614410602083018a6143de565b61441d60408301896143cf565b61442a6060830188613f2f565b6144376080830187613c3e565b61444460a0830186613c3e565b61445160c0830185613c3e565b61445e60e0830184613c3e565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006144d860338361446b565b91506144e38261447c565b604082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b600061456a60238361446b565b91506145758261450e565b604082019050919050565b600060208201905081810360008301526145998161455d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145d6601f8361446b565b91506145e1826145a0565b602082019050919050565b60006020820190508181036000830152614605816145c9565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b600061464260118361446b565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b600061472060658361446b565b915061472b82614678565b608082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b600061478c601d8361446b565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147fc82613c34565b915061480783613c34565b925082820390508181111561481f5761481e6147c2565b5b92915050565b600060408201905061483a6000830185613f2f565b6148476020830184613c3e565b9392505050565b61485781613eb9565b811461486257600080fd5b50565b6000815190506148748161484e565b92915050565b6000602082840312156148905761488f613c68565b5b600061489e84828501614865565b91505092915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b600061490360338361446b565b915061490e826148a7565b604082019050919050565b60006020820190508181036000830152614932816148f6565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b600061499560368361446b565b91506149a082614939565b604082019050919050565b600060208201905081810360008301526149c481614988565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614a27603e8361446b565b9150614a32826149cb565b604082019050919050565b60006020820190508181036000830152614a5681614a1a565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614ab960258361446b565b9150614ac482614a5d565b604082019050919050565b60006020820190508181036000830152614ae881614aac565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614b4b60328361446b565b9150614b5682614aef565b604082019050919050565b60006020820190508181036000830152614b7a81614b3e565b9050919050565b600060ff82169050919050565b614b9781614b81565b8114614ba257600080fd5b50565b600081519050614bb481614b8e565b92915050565b600060208284031215614bd057614bcf613c68565b5b6000614bde84828501614ba5565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614c3e57808604811115614c1a57614c196147c2565b5b6001851615614c295780820291505b8081029050614c3785614be7565b9450614bfe565b94509492505050565b600082614c575760019050614d13565b81614c655760009050614d13565b8160018114614c7b5760028114614c8557614cb4565b6001915050614d13565b60ff841115614c9757614c966147c2565b5b8360020a915084821115614cae57614cad6147c2565b5b50614d13565b5060208310610133831016604e8410600b8410161715614ce95782820a905083811115614ce457614ce36147c2565b5b614d13565b614cf68484846001614bf4565b92509050818404811115614d0d57614d0c6147c2565b5b81810290505b9392505050565b6000614d2582613c34565b9150614d3083614b81565b9250614d5d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614c47565b905092915050565b6000614d7082613c34565b9150614d7b83613c34565b9250828202614d8981613c34565b91508282048414831517614da057614d9f6147c2565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614de182613c34565b9150614dec83613c34565b925082614dfc57614dfb614da7565b5b828204905092915050565b6000614e1282613c34565b9150614e1d83613c34565b9250828201905080821115614e3557614e346147c2565b5b92915050565b6000614e4682613c34565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e7857614e776147c2565b5b600182019050919050565b6000819050919050565b6000614ea8614ea3614e9e84614e83565b613fd5565b613c34565b9050919050565b614eb881614e8d565b82525050565b6000602082019050614ed36000830184614eaf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b6000614f9360348361446b565b9150614f9e82614f37565b604082019050919050565b60006020820190508181036000830152614fc281614f86565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b600061504b604d8361446b565b915061505682614fc9565b606082019050919050565b6000602082019050818103600083015261507a8161503e565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006150dd60308361446b565b91506150e882615081565b604082019050919050565b6000602082019050818103600083015261510c816150d0565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006151508385615113565b935061515d838584615124565b61516683615133565b840190509392505050565b6000602082019050818103600083015261518c818486615144565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006151cb600e8361446b565b91506151d682615195565b602082019050919050565b600060208201905081810360008301526151fa816151be565b9050919050565b60006060820190506152166000830186613f2f565b6152236020830185613f2f565b6152306040830184613c3e565b949350505050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061529460378361446b565b915061529f82615238565b604082019050919050565b600060208201905081810360008301526152c381615287565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b6000615326603c8361446b565b9150615331826152ca565b604082019050919050565b6000602082019050818103600083015261535581615319565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b60006153b860228361446b565b91506153c38261535c565b604082019050919050565b600060208201905081810360008301526153e7816153ab565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b600061544a60218361446b565b9150615455826153ee565b604082019050919050565b600060208201905081810360008301526154798161543d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006154dc60268361446b565b91506154e782615480565b604082019050919050565b6000602082019050818103600083015261550b816154cf565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061554860208361446b565b915061555382615512565b602082019050919050565b600060208201905081810360008301526155778161553b565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006155b460108361446b565b91506155bf8261557e565b602082019050919050565b600060208201905081810360008301526155e3816155a7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212201cdc9d5ba326b01aa0d9981853263ca20b434dbf4172c9f057a8b3e26cb89cc564736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613c4d565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613cd0565b610a75565b6040516103609190613c4d565b60405180910390f35b610383600480360381019061037e9190613cd0565b610ac1565b005b61039f600480360381019061039a9190613d29565b610b44565b005b6103bb60048036038101906103b69190613d29565b610b90565b005b6103d760048036038101906103d29190613d29565b610bd9565b005b6103f360048036038101906103ee9190613dda565b610eea565b005b6103fd61143f565b005b610407611888565b005b610423600480360381019061041e9190613e8c565b611a68565b005b61043f600480360381019061043a9190613cd0565b611ad4565b60405161044c9190613ed4565b60405180910390f35b61046f600480360381019061046a9190613d29565b611af1565b005b61048b60048036038101906104869190613eef565b611b3a565b6040516104989190613c4d565b60405180910390f35b6104bb60048036038101906104b69190613dda565b611b65565b005b6104d760048036038101906104d29190613cd0565b611db7565b6040516104e49190613f3e565b60405180910390f35b61050760048036038101906105029190613cd0565b611dea565b6040516105149190613ed4565b60405180910390f35b61053760048036038101906105329190613d29565b611e0a565b005b610541611e56565b60405161054e9190613ed4565b60405180910390f35b610571600480360381019061056c9190613cd0565b611e6d565b60405161057e9190613c4d565b60405180910390f35b6105a1600480360381019061059c9190613f59565b611eb9565b6040516105af929190613fac565b60405180910390f35b6105c0611f71565b005b6105ca611f85565b6040516105d79190614034565b60405180910390f35b6105fa60048036038101906105f59190613cd0565b611fab565b005b610604612084565b6040516106119190613c4d565b60405180910390f35b610634600480360381019061062f9190613cd0565b61208a565b6040516106419190613ed4565b60405180910390f35b61065261210b565b60405161065f919061410d565b60405180910390f35b610682600480360381019061067d9190614194565b6121f9565b005b61069e60048036038101906106999190614208565b6127eb565b005b6106a8612999565b6040516106b59190613ed4565b60405180910390f35b6106c66129d7565b6040516106d39190613f3e565b60405180910390f35b6106e46129ff565b6040516106f5959493929190614248565b60405180910390f35b61071860048036038101906107139190613cd0565b612a23565b005b610722612aa6565b60405161072f9190613ed4565b60405180910390f35b610752600480360381019061074d9190613d29565b612ae3565b005b61075c612ce1565b005b610766612e9b565b005b610770612f08565b60405161077d9190613f3e565b60405180910390f35b61078e612f2e565b60405161079b9190613c4d565b60405180910390f35b6107be60048036038101906107b9919061429b565b612f34565b005b6107c8612f5c565b005b6107d26131f2565b005b6107dc6133e6565b6040516107e991906143b4565b60405180910390f35b6107fa6133f9565b604051610807919061410d565b60405180910390f35b6108186134e7565b6040516108259190613c4d565b60405180910390f35b61084860048036038101906108439190613d29565b61352b565b005b610852613574565b005b61085c6135c9565b6040516108699190613c4d565b60405180910390f35b61087a6135cf565b6040516108879190613ed4565b60405180910390f35b6108aa60048036038101906108a59190613cd0565b61369a565b005b6108b461371d565b6040516108c19190613ed4565b60405180910390f35b6108e460048036038101906108df9190613cd0565b61375b565b6040516108f89897969594939291906143ed565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610946906144ee565b60405180910390fd5b600060048111156109635761096261433d565b5b600160159054906101000a900460ff1660048111156109855761098461433d565b5b14806109c45750600360048111156109a05761099f61433d565b5b600160159054906101000a900460ff1660048111156109c2576109c161433d565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614580565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a2761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b91906143b4565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac96137ff565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b399190613f3e565b60405180910390a150565b610b4c6137ff565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613c4d565b60405180910390a150565b610b986137ff565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613c4d565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c15906145ec565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6090614658565b60405180910390fd5b60001515610c8133600c61387d90919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90614736565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f906147a2565b60405180910390fd5b80600a54610d5691906147f1565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa91906147f1565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610e4d929190614825565b6020604051808303816000875af1158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e90919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610ed79190613c4d565b60405180910390a2600160008190555050565b600260005403610f2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f26906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610fc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fba90614919565b60405180910390fd5b60006004811115610fd757610fd661433d565b5b600160159054906101000a900460ff166004811115610ff957610ff861433d565b5b14806110385750600360048111156110145761101361433d565b5b600160159054906101000a900460ff1660048111156110365761103561433d565b5b145b8061107557506004808111156110515761105061433d565b5b600160159054906101000a900460ff1660048111156110735761107261433d565b5b145b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ab906149ab565b60405180910390fd5b600015156110cc33601061387d90919063ffffffff16565b15151461110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590614a3d565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea33600e6138ad90919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147e906144ee565b60405180910390fd5b6002600481111561149b5761149a61433d565b5b600160159054906101000a900460ff1660048111156114bd576114bc61433d565b5b146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f490614acf565b60405180910390fd5b600115156115096135cf565b15151461154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154290614b61565b60405180910390fd5b6000611557600c6138dd565b905060005b818110156116df57600061157a82600c6138f290919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190614bba565b600a6116199190614d1a565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116699190614d65565b6116739190614dd6565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116c49190614e07565b925050819055505080806116d790614e3b565b91505061155c565b505b60006116ed600c6138dd565b11156117215761171b61170b6000600c6138f290919063ffffffff16565b600c61390c90919063ffffffff16565b506116e1565b61172b600e6138dd565b905060005b818110156117de5761175f61174f82600e6138f290919063ffffffff16565b600c6138ad90919063ffffffff16565b5060006014600061177a84600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806117d690614e3b565b915050611730565b50600360010160008154809291906117f590614e3b565b91905055506003600001544361180b9190614e07565b6003600201819055506000600160156101000a81548160ff0219169083600481111561183a5761183961433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff1660405161187d91906143b4565b60405180910390a150565b6002600054036118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000811115611a5d576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016119ca929190614825565b6020604051808303816000875af11580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611a549190613c4d565b60405180910390a25b506001600081905550565b611a706137ff565b80600160156101000a81548160ff02191690836004811115611a9557611a9461433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611ac991906143b4565b60405180910390a150565b6000611aea82600c61387d90919063ffffffff16565b9050919050565b611af96137ff565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611b2f9190613c4d565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611e126137ff565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611e4b9190613c4d565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611f796137ff565b611f83600061393c565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe7906145ec565b60405180910390fd5b60026000819055506120006137ff565b61201481600e61390c90919063ffffffff16565b506120298160106138ad90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e9760006040516120719190614ebe565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120ec6134e7565b816000015410612100576001915050612106565b60009150505b919050565b60606000612119600c6138dd565b67ffffffffffffffff81111561213257612131614ed9565b5b6040519080825280602002602001820160405280156121605781602001602082028036833780820191505090505b509050600061216f600c6138dd565b905060005b818110156121f05761219081600c6138f290919063ffffffff16565b8382815181106121a3576121a2614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806121e890614e3b565b915050612174565b50819250505090565b60026000540361223e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612235906145ec565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fa9565b60405180910390fd5b61232d81600e61387d90919063ffffffff16565b61236c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236390615061565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c906150f3565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008154809291906124be90614e3b565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061258585600e61387d90919063ffffffff16565b801561259657506125958561208a565b5b15612774576125af85600e61390c90919063ffffffff16565b506125c48560106138ad90919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546126199190614d65565b6126239190614dd6565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461267791906147f1565b9250508190555080600a600082825461269091906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016126f29190613c4d565b600060405180830381600087803b15801561270c57600080fd5b505af1158015612720573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e978260405161276a9190613c4d565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa86866040516127d4929190615171565b60405180910390a450600160008190555050505050565b600260005403612830576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612827906145ec565b60405180910390fd5b60026000819055506128406137ff565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461289291906147f1565b9250508190555080600a60008282546128ab91906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161290d9190613c4d565b600060405180830381600087803b15801561292757600080fd5b505af115801561293b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516129859190613c4d565b60405180910390a260016000819055505050565b6000600160048111156129af576129ae61433d565b5b600160159054906101000a900460ff1660048111156129d1576129d061433d565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612a2b6137ff565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a607581604051612a9b9190613f3e565b60405180910390a150565b6000806004811115612abb57612aba61433d565b5b600160159054906101000a900460ff166004811115612add57612adc61433d565b5b14905090565b600260005403612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f906145ec565b60405180910390fd5b600260008190555060008111612b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6a906151e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401612bd293929190615201565b6020604051808303816000875af1158015612bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c15919061487a565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612c689190614e07565b9250508190555080600a6000828254612c819190614e07565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612cce9190613c4d565b60405180910390a2600160008190555050565b600260005403612d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1d906145ec565b60405180910390fd5b600260008190555060006004811115612d4257612d4161433d565b5b600160159054906101000a900460ff166004811115612d6457612d6361433d565b5b1480612da3575060036004811115612d7f57612d7e61433d565b5b600160159054906101000a900460ff166004811115612da157612da061433d565b5b145b80612de05750600480811115612dbc57612dbb61433d565b5b600160159054906101000a900460ff166004811115612dde57612ddd61433d565b5b145b612e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e16906152aa565b60405180910390fd5b612e3333600e61387d90919063ffffffff16565b15612e4e57612e4c33600e61390c90919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612ea36137ff565b6004600160156101000a81548160ff02191690836004811115612ec957612ec861433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612efe91906143b4565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612f3c6139ff565b612f4587612ae3565b612f53868686868686610eea565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612fd457612fd361433d565b5b600160159054906101000a900460ff166004811115612ff657612ff561433d565b5b14806130355750600260048111156130115761301061433d565b5b600160159054906101000a900460ff1660048111156130335761303261433d565b5b145b613074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306b9061533c565b60405180910390fd5b6001600360010154146130d55761309581600e61387d90919063ffffffff16565b6130d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cb906153ce565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a26131786135cf565b156131ef576002600160156101000a81548160ff021916908360048111156131a3576131a261433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516131e691906143b4565b60405180910390a15b50565b6003600401546003600201546132089190614e07565b43101561324a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613241906144ee565b60405180910390fd5b6001600481111561325e5761325d61433d565b5b600160159054906101000a900460ff1660048111156132805761327f61433d565b5b146132c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132b790615460565b60405180910390fd5b60006132cc600e6138dd565b905060005b81811015613357576000601460006132f384600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061334f90614e3b565b9150506132d1565b5060038001600081548092919061336d90614e3b565b91905055506003600160156101000a81548160ff021916908360048111156133985761339761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516133db91906143b4565b60405180910390a150565b600160159054906101000a900460ff1681565b60606000613407600e6138dd565b67ffffffffffffffff8111156134205761341f614ed9565b5b60405190808252806020026020018201604052801561344e5781602001602082028036833780820191505090505b509050600061345d600e6138dd565b905060005b818110156134de5761347e81600e6138f290919063ffffffff16565b83828151811061349157613490614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806134d690614e3b565b915050613462565b50819250505090565b600060026134f5600c6138dd565b116135035760019050613528565b60036002613511600c6138dd565b61351b9190614d65565b6135259190614dd6565b90505b90565b6135336137ff565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a5816040516135699190613c4d565b60405180910390a150565b6135bf601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6135c7611888565b565b60095481565b6000806000905060006135e2600e6138dd565b905060005b81811015613676576014600061360783600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561366357828061365f90614e3b565b9350505b808061366e90614e3b565b9150506135e7565b5061367f6134e7565b821061369057600192505050613697565b6000925050505b90565b6136a26137ff565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613711576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613708906154f2565b60405180910390fd5b61371a8161393c565b50565b6000600360048111156137335761373261433d565b5b600160159054906101000a900460ff1660048111156137555761375461433d565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b613807613a49565b73ffffffffffffffffffffffffffffffffffffffff166138256129d7565b73ffffffffffffffffffffffffffffffffffffffff161461387b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138729061555e565b60405180910390fd5b565b60006138a5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a51565b905092915050565b60006138d5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a74565b905092915050565b60006138eb82600001613ae4565b9050919050565b60006139018360000183613af5565b60001c905092915050565b6000613934836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b20565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a07611e56565b15613a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a3e906155ca565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613a808383613a51565b613ad9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613ade565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613b0d57613b0c614f08565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613c28576000600182613b5291906147f1565b9050600060018660000180549050613b6a91906147f1565b9050818114613bd9576000866000018281548110613b8b57613b8a614f08565b5b9060005260206000200154905080876000018481548110613baf57613bae614f08565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613bed57613bec6155ea565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613c2e565b60009150505b92915050565b6000819050919050565b613c4781613c34565b82525050565b6000602082019050613c626000830184613c3e565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c9d82613c72565b9050919050565b613cad81613c92565b8114613cb857600080fd5b50565b600081359050613cca81613ca4565b92915050565b600060208284031215613ce657613ce5613c68565b5b6000613cf484828501613cbb565b91505092915050565b613d0681613c34565b8114613d1157600080fd5b50565b600081359050613d2381613cfd565b92915050565b600060208284031215613d3f57613d3e613c68565b5b6000613d4d84828501613d14565b91505092915050565b600063ffffffff82169050919050565b613d6f81613d56565b8114613d7a57600080fd5b50565b600081359050613d8c81613d66565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613db781613d92565b8114613dc257600080fd5b50565b600081359050613dd481613dae565b92915050565b60008060008060008060c08789031215613df757613df6613c68565b5b6000613e0589828a01613d7d565b9650506020613e1689828a01613dc5565b9550506040613e2789828a01613d7d565b9450506060613e3889828a01613cbb565b9350506080613e4989828a01613d14565b92505060a0613e5a89828a01613d14565b9150509295509295509295565b60058110613e7457600080fd5b50565b600081359050613e8681613e67565b92915050565b600060208284031215613ea257613ea1613c68565b5b6000613eb084828501613e77565b91505092915050565b60008115159050919050565b613ece81613eb9565b82525050565b6000602082019050613ee96000830184613ec5565b92915050565b60008060408385031215613f0657613f05613c68565b5b6000613f1485828601613d14565b9250506020613f2585828601613cbb565b9150509250929050565b613f3881613c92565b82525050565b6000602082019050613f536000830184613f2f565b92915050565b600080600060608486031215613f7257613f71613c68565b5b6000613f8086828701613d14565b9350506020613f9186828701613cbb565b9250506040613fa286828701613cbb565b9150509250925092565b6000604082019050613fc16000830185613c3e565b613fce6020830184613ec5565b9392505050565b6000819050919050565b6000613ffa613ff5613ff084613c72565b613fd5565b613c72565b9050919050565b600061400c82613fdf565b9050919050565b600061401e82614001565b9050919050565b61402e81614013565b82525050565b60006020820190506140496000830184614025565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61408481613c92565b82525050565b6000614096838361407b565b60208301905092915050565b6000602082019050919050565b60006140ba8261404f565b6140c4818561405a565b93506140cf8361406b565b8060005b838110156141005781516140e7888261408a565b97506140f2836140a2565b9250506001810190506140d3565b5085935050505092915050565b6000602082019050818103600083015261412781846140af565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141545761415361412f565b5b8235905067ffffffffffffffff81111561417157614170614134565b5b60208301915083600182028301111561418d5761418c614139565b5b9250929050565b600080600080606085870312156141ae576141ad613c68565b5b60006141bc87828801613cbb565b94505060206141cd87828801613d14565b935050604085013567ffffffffffffffff8111156141ee576141ed613c6d565b5b6141fa8782880161413e565b925092505092959194509250565b6000806040838503121561421f5761421e613c68565b5b600061422d85828601613cbb565b925050602061423e85828601613d14565b9150509250929050565b600060a08201905061425d6000830188613c3e565b61426a6020830187613c3e565b6142776040830186613c3e565b6142846060830185613c3e565b6142916080830184613c3e565b9695505050505050565b600080600080600080600060e0888a0312156142ba576142b9613c68565b5b60006142c88a828b01613d14565b97505060206142d98a828b01613d7d565b96505060406142ea8a828b01613dc5565b95505060606142fb8a828b01613d7d565b945050608061430c8a828b01613cbb565b93505060a061431d8a828b01613d14565b92505060c061432e8a828b01613d14565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061437d5761437c61433d565b5b50565b600081905061438e8261436c565b919050565b600061439e82614380565b9050919050565b6143ae81614393565b82525050565b60006020820190506143c960008301846143a5565b92915050565b6143d881613d56565b82525050565b6143e781613d92565b82525050565b600061010082019050614403600083018b6143cf565b614410602083018a6143de565b61441d60408301896143cf565b61442a6060830188613f2f565b6144376080830187613c3e565b61444460a0830186613c3e565b61445160c0830185613c3e565b61445e60e0830184613c3e565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006144d860338361446b565b91506144e38261447c565b604082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b600061456a60238361446b565b91506145758261450e565b604082019050919050565b600060208201905081810360008301526145998161455d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145d6601f8361446b565b91506145e1826145a0565b602082019050919050565b60006020820190508181036000830152614605816145c9565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b600061464260118361446b565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b600061472060658361446b565b915061472b82614678565b608082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b600061478c601d8361446b565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147fc82613c34565b915061480783613c34565b925082820390508181111561481f5761481e6147c2565b5b92915050565b600060408201905061483a6000830185613f2f565b6148476020830184613c3e565b9392505050565b61485781613eb9565b811461486257600080fd5b50565b6000815190506148748161484e565b92915050565b6000602082840312156148905761488f613c68565b5b600061489e84828501614865565b91505092915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b600061490360338361446b565b915061490e826148a7565b604082019050919050565b60006020820190508181036000830152614932816148f6565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b600061499560368361446b565b91506149a082614939565b604082019050919050565b600060208201905081810360008301526149c481614988565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614a27603e8361446b565b9150614a32826149cb565b604082019050919050565b60006020820190508181036000830152614a5681614a1a565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614ab960258361446b565b9150614ac482614a5d565b604082019050919050565b60006020820190508181036000830152614ae881614aac565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614b4b60328361446b565b9150614b5682614aef565b604082019050919050565b60006020820190508181036000830152614b7a81614b3e565b9050919050565b600060ff82169050919050565b614b9781614b81565b8114614ba257600080fd5b50565b600081519050614bb481614b8e565b92915050565b600060208284031215614bd057614bcf613c68565b5b6000614bde84828501614ba5565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614c3e57808604811115614c1a57614c196147c2565b5b6001851615614c295780820291505b8081029050614c3785614be7565b9450614bfe565b94509492505050565b600082614c575760019050614d13565b81614c655760009050614d13565b8160018114614c7b5760028114614c8557614cb4565b6001915050614d13565b60ff841115614c9757614c966147c2565b5b8360020a915084821115614cae57614cad6147c2565b5b50614d13565b5060208310610133831016604e8410600b8410161715614ce95782820a905083811115614ce457614ce36147c2565b5b614d13565b614cf68484846001614bf4565b92509050818404811115614d0d57614d0c6147c2565b5b81810290505b9392505050565b6000614d2582613c34565b9150614d3083614b81565b9250614d5d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614c47565b905092915050565b6000614d7082613c34565b9150614d7b83613c34565b9250828202614d8981613c34565b91508282048414831517614da057614d9f6147c2565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614de182613c34565b9150614dec83613c34565b925082614dfc57614dfb614da7565b5b828204905092915050565b6000614e1282613c34565b9150614e1d83613c34565b9250828201905080821115614e3557614e346147c2565b5b92915050565b6000614e4682613c34565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e7857614e776147c2565b5b600182019050919050565b6000819050919050565b6000614ea8614ea3614e9e84614e83565b613fd5565b613c34565b9050919050565b614eb881614e8d565b82525050565b6000602082019050614ed36000830184614eaf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b6000614f9360348361446b565b9150614f9e82614f37565b604082019050919050565b60006020820190508181036000830152614fc281614f86565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b600061504b604d8361446b565b915061505682614fc9565b606082019050919050565b6000602082019050818103600083015261507a8161503e565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006150dd60308361446b565b91506150e882615081565b604082019050919050565b6000602082019050818103600083015261510c816150d0565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006151508385615113565b935061515d838584615124565b61516683615133565b840190509392505050565b6000602082019050818103600083015261518c818486615144565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006151cb600e8361446b565b91506151d682615195565b602082019050919050565b600060208201905081810360008301526151fa816151be565b9050919050565b60006060820190506152166000830186613f2f565b6152236020830185613f2f565b6152306040830184613c3e565b949350505050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061529460378361446b565b915061529f82615238565b604082019050919050565b600060208201905081810360008301526152c381615287565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b6000615326603c8361446b565b9150615331826152ca565b604082019050919050565b6000602082019050818103600083015261535581615319565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b60006153b860228361446b565b91506153c38261535c565b604082019050919050565b600060208201905081810360008301526153e7816153ab565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b600061544a60218361446b565b9150615455826153ee565b604082019050919050565b600060208201905081810360008301526154798161543d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006154dc60268361446b565b91506154e782615480565b604082019050919050565b6000602082019050818103600083015261550b816154cf565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061554860208361446b565b915061555382615512565b602082019050919050565b600060208201905081810360008301526155778161553b565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006155b460108361446b565b91506155bf8261557e565b602082019050919050565b600060208201905081810360008301526155e3816155a7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212201cdc9d5ba326b01aa0d9981853263ca20b434dbf4172c9f057a8b3e26cb89cc564736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"EpochLengthSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"EpochTimeoutSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"KickPenaltyPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"MinimumStakeSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"ReadyForNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"ResolverContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"StakingTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"StateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"TokenRewardPerTokenPerEpochSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBurned","type":"uint256"}],"name":"ValidatorKickedFromNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reporter","type":"address"},{"indexed":true,"internalType":"address","name":"validatorStakerAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"reason","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"VotedToKickValidatorInNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"}],"name":"adminKickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"amountToBurn","type":"uint256"}],"name":"adminSlashValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"advanceEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"epochLength","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"retries","type":"uint256"},{"internalType":"uint256","name":"timeout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValidatorsInCurrentEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorsInNextEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochNumber","type":"uint256"},{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"address","name":"voterStakerAddress","type":"address"}],"name":"getVotingStatusToKickValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isActiveValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReadyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickPenaltyPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"reason","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"kickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nodeAddressToStakerAddress","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":"pauseEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"requestToJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestToLeave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolverContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"setEpochLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"setEpochState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"setEpochTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"setIpPortNodeAddressAndCommunicationPubKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"setKickPenaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"setResolverContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"setStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"setTokenRewardPerTokenPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"shouldKickValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signalReadyForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"stakeAndJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract ERC20Burnable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Staking.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenRewardPerTokenPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorCountForConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsInNextEpochAreLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votesToKickValidatorsInNextEpoch","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/AccessControlConditions.json b/deployments/littestnet_987/AccessControlConditions.json deleted file mode 100644 index 05dac96..0000000 --- a/deployments/littestnet_987/AccessControlConditions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/AccessControlConditions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract AccessControlConditions is Ownable, ReentrancyGuard {\\n /* ========== STRUCTS ========== */\\n struct StoredCondition {\\n uint256 value;\\n uint256 securityHash;\\n uint256 chainId;\\n bool permanent;\\n address creator;\\n }\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(uint256 => StoredCondition) public storedConditions;\\n address public signer;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n signer = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function getCondition(uint256 key)\\n external\\n view\\n returns (StoredCondition memory)\\n {\\n return storedConditions[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent\\n ) external nonReentrant {\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n msg.sender\\n );\\n }\\n\\n function storeConditionWithSigner(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) external nonReentrant {\\n require(\\n msg.sender == signer,\\n \\\"Only signer can call storeConditionsWithSigner.\\\"\\n );\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n }\\n\\n function setSigner(address newSigner) public onlyOwner {\\n signer = newSigner;\\n }\\n\\n /* ========== PRIVATE FUNCTIONS ========== */\\n\\n function _storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) private {\\n require(key != 0, \\\"Key must not be zero\\\");\\n if (storedConditions[key].creator != address(0)) {\\n // this is an update\\n require(\\n storedConditions[key].creator == creatorAddress,\\n \\\"Only the condition creator can update it\\\"\\n );\\n require(\\n storedConditions[key].permanent == false,\\n \\\"This condition was stored with the Permanent flag and cannot be updated\\\"\\n );\\n require(msg.sender != signer, \\\"Signer cannot update conditions\\\");\\n }\\n storedConditions[key] = StoredCondition(\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n\\n emit ConditionStored(key, value, chainId, permanent, creatorAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ConditionStored(\\n uint256 indexed key,\\n uint256 value,\\n uint256 chainId,\\n bool permanent,\\n address creator\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xeC146428E70Dbc779BB2B358646C8F52ec858d8D","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261007a60201b60201c565b61008260201b60201c565b6001808190555033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610146565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61128b806101556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"permanent","type":"bool"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"ConditionStored","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":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getCondition","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"internalType":"struct AccessControlConditions.StoredCondition","name":"","type":"tuple"}],"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":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"}],"name":"storeCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"storeConditionWithSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"storedConditions","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/Allowlist.json b/deployments/littestnet_987/Allowlist.json deleted file mode 100644 index e6fcf20..0000000 --- a/deployments/littestnet_987/Allowlist.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Allowlist.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Allowlist is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(bytes32 => bool) public allowedItems;\\n EnumerableSet.AddressSet admins;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n admins.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function isAllowed(bytes32 key) external view returns (bool) {\\n return allowedItems[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function setAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = true;\\n emit ItemAllowed(key);\\n }\\n\\n function setNotAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = false;\\n emit ItemNotAllowed(key);\\n }\\n\\n function addAdmin(address newAdmin) public onlyOwner {\\n admins.add(newAdmin);\\n emit AdminAdded(newAdmin);\\n }\\n\\n function removeAdmin(address newAdmin) public onlyOwner {\\n admins.remove(newAdmin);\\n emit AdminRemoved(newAdmin);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ItemAllowed(bytes32 indexed key);\\n event ItemNotAllowed(bytes32 indexed key);\\n event AdminAdded(address indexed newAdmin);\\n event AdminRemoved(address indexed newAdmin);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x6d75DB98eDa4Eac5FFc497e88f75825b97EE68F9","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261005260201b60201c565b61005a60201b60201c565b6001808190555061004c33600361011e60201b6104da1790919060201c565b506101ed565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061014c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61015460201b60201c565b905092915050565b600061016683836101ca60201b60201c565b6101bf5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506101c4565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b610c2a806101fc6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemNotAllowed","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":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"allowedItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/LITToken.json b/deployments/littestnet_987/LITToken.json deleted file mode 100644 index 1568152..0000000 --- a/deployments/littestnet_987/LITToken.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x39dc434A2404973b5Eba328Ee09ba78Fb1B12610","bytecode":"0x6101606040523480156200001257600080fd5b5060405162005abe38038062005abe833981810160405281019062000038919062000640565b6040518060400160405280600c81526020017f4c69742050726f746f636f6c0000000000000000000000000000000000000000815250806040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250836040518060400160405280600c81526020017f4c69742050726f746f636f6c00000000000000000000000000000000000000008152506040518060400160405280600381526020017f4c495400000000000000000000000000000000000000000000000000000000008152508160049081620001239190620008e2565b508060059081620001359190620008e2565b505050600081116200017e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001759062000a2a565b60405180910390fd5b8060808181525050506000600660006101000a81548160ff02191690831515021790555060008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508261010081815250508161012081815250504660c081815250506200020c818484620003c960201b60201c565b60a081815250503073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1681525050806101408181525050505050505050620002887fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42336200040560201b60201c565b620002ba7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9336200040560201b60201c565b620002ec7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a336200040560201b60201c565b6200033e7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc97fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec426200041b60201b60201c565b620003707fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42806200041b60201b60201c565b620003c27f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec426200041b60201b60201c565b5062000b1a565b60008383834630604051602001620003e695949392919062000abd565b6040516020818303038152906040528051906020012090509392505050565b6200041782826200047e60201b60201c565b5050565b60006200042e836200056f60201b60201c565b905081600080858152602001908152602001600020600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b6200049082826200058e60201b60201c565b6200056b57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555062000510620005f860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000806000838152602001908152602001600020600101549050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b6000819050919050565b6200061a8162000605565b81146200062657600080fd5b50565b6000815190506200063a816200060f565b92915050565b60006020828403121562000659576200065862000600565b5b6000620006698482850162000629565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620006f457607f821691505b6020821081036200070a5762000709620006ac565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620007747fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000735565b62000780868362000735565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620007c3620007bd620007b78462000605565b62000798565b62000605565b9050919050565b6000819050919050565b620007df83620007a2565b620007f7620007ee82620007ca565b84845462000742565b825550505050565b600090565b6200080e620007ff565b6200081b818484620007d4565b505050565b5b8181101562000843576200083760008262000804565b60018101905062000821565b5050565b601f82111562000892576200085c8162000710565b620008678462000725565b8101602085101562000877578190505b6200088f620008868562000725565b83018262000820565b50505b505050565b600082821c905092915050565b6000620008b76000198460080262000897565b1980831691505092915050565b6000620008d28383620008a4565b9150826002028217905092915050565b620008ed8262000672565b67ffffffffffffffff8111156200090957620009086200067d565b5b620009158254620006db565b6200092282828562000847565b600060209050601f8311600181146200095a576000841562000945578287015190505b620009518582620008c4565b865550620009c1565b601f1984166200096a8662000710565b60005b8281101562000994578489015182556001820191506020850194506020810190506200096d565b86831015620009b45784890151620009b0601f891682620008a4565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f45524332304361707065643a2063617020697320300000000000000000000000600082015250565b600062000a12601583620009c9565b915062000a1f82620009da565b602082019050919050565b6000602082019050818103600083015262000a458162000a03565b9050919050565b6000819050919050565b62000a618162000a4c565b82525050565b62000a728162000605565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000aa58262000a78565b9050919050565b62000ab78162000a98565b82525050565b600060a08201905062000ad4600083018862000a56565b62000ae3602083018762000a56565b62000af2604083018662000a56565b62000b01606083018562000a67565b62000b10608083018462000aac565b9695505050505050565b60805160a05160c05160e051610100516101205161014051614f4962000b756000396000611c7b01526000611cbd01526000611c9c01526000611bd101526000611c2701526000611c50015260006109810152614f496000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b578063a217fddf116100b8578063d53913931161007c578063d539139314610714578063d547741f14610732578063dd62ed3e1461074e578063e63ab1e91461077e578063f1127ed81461079c5761023d565b8063a217fddf1461065e578063a457c2d71461067c578063a9059cbb146106ac578063c3cda520146106dc578063d505accf146106f85761023d565b80638456cb59116100ff5780638456cb59146105a65780638e539e8c146105b057806391d14854146105e057806395d89b41146106105780639ab24eb01461062e5761023d565b80636fcfff45146104dc57806370a082311461050c57806375b238fc1461053c57806379cc67901461055a5780637ecebe00146105765761023d565b80633644e515116101c957806340c10f191161018d57806340c10f191461043a57806342966c6814610456578063587cde1e146104725780635c19a95c146104a25780635c975abb146104be5761023d565b80633644e5151461039657806336568abe146103b457806339509351146103d05780633a46b1a8146104005780633f4ba83a146104305761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a578063355274ea146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613352565b6107cc565b604051610269919061339a565b60405180910390f35b61027a610846565b6040516102879190613445565b60405180910390f35b6102aa60048036038101906102a591906134fb565b6108d8565b6040516102b7919061339a565b60405180910390f35b6102c86108fb565b6040516102d5919061354a565b60405180910390f35b6102f860048036038101906102f39190613565565b610905565b604051610305919061339a565b60405180910390f35b610328600480360381019061032391906135ee565b610934565b604051610335919061362a565b60405180910390f35b61035860048036038101906103539190613645565b610953565b005b610362610974565b60405161036f91906136a1565b60405180910390f35b61038061097d565b60405161038d919061354a565b60405180910390f35b61039e6109a5565b6040516103ab919061362a565b60405180910390f35b6103ce60048036038101906103c99190613645565b6109b4565b005b6103ea60048036038101906103e591906134fb565b610a37565b6040516103f7919061339a565b60405180910390f35b61041a600480360381019061041591906134fb565b610a6e565b604051610427919061354a565b60405180910390f35b610438610b02565b005b610454600480360381019061044f91906134fb565b610b7c565b005b610470600480360381019061046b91906136bc565b610bf3565b005b61048c600480360381019061048791906136e9565b610c07565b6040516104999190613725565b60405180910390f35b6104bc60048036038101906104b791906136e9565b610c70565b005b6104c6610c84565b6040516104d3919061339a565b60405180910390f35b6104f660048036038101906104f191906136e9565b610c9b565b604051610503919061375f565b60405180910390f35b610526600480360381019061052191906136e9565b610cef565b604051610533919061354a565b60405180910390f35b610544610d38565b604051610551919061362a565b60405180910390f35b610574600480360381019061056f91906134fb565b610d5c565b005b610590600480360381019061058b91906136e9565b610d7c565b60405161059d919061354a565b60405180910390f35b6105ae610dcc565b005b6105ca60048036038101906105c591906136bc565b610e46565b6040516105d7919061354a565b60405180910390f35b6105fa60048036038101906105f59190613645565b610e9c565b604051610607919061339a565b60405180910390f35b610618610f06565b6040516106259190613445565b60405180910390f35b610648600480360381019061064391906136e9565b610f98565b604051610655919061354a565b60405180910390f35b6106666110a9565b604051610673919061362a565b60405180910390f35b610696600480360381019061069191906134fb565b6110b0565b6040516106a3919061339a565b60405180910390f35b6106c660048036038101906106c191906134fb565b611127565b6040516106d3919061339a565b60405180910390f35b6106f660048036038101906106f191906137a6565b61114a565b005b610712600480360381019061070d9190613833565b61124e565b005b61071c611390565b604051610729919061362a565b60405180910390f35b61074c60048036038101906107479190613645565b6113b4565b005b610768600480360381019061076391906138d5565b6113d5565b604051610775919061354a565b60405180910390f35b61078661145c565b604051610793919061362a565b60405180910390f35b6107b660048036038101906107b19190613941565b611480565b6040516107c391906139f6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083f575061083e82611590565b5b9050919050565b60606004805461085590613a40565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613a40565b80156108ce5780601f106108a3576101008083540402835291602001916108ce565b820191906000526020600020905b8154815290600101906020018083116108b157829003601f168201915b5050505050905090565b6000806108e36115fa565b90506108f0818585611602565b600191505092915050565b6000600354905090565b6000806109106115fa565b905061091d8582856117cb565b610928858585611857565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61095c82610934565b61096581611ad9565b61096f8383611aed565b505050565b60006012905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60006109af611bcd565b905090565b6109bc6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2090613ae3565b60405180910390fd5b610a338282611ce7565b5050565b600080610a426115fa565b9050610a63818585610a5485896113d5565b610a5e9190613b32565b611602565b600191505092915050565b6000438210610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990613bb2565b60405180910390fd5b610afa600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083611dc8565b905092915050565b610b337f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b2e6115fa565b610e9c565b610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613c44565b60405180910390fd5b610b7a611ed4565b565b610ba67ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc933610e9c565b610be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdc90613cb0565b60405180910390fd5b610bef8282611f37565b5050565b610c04610bfe6115fa565b82611f45565b50565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6115fa565b82611f53565b50565b6000600660009054906101000a900460ff16905090565b6000610ce8600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061206d565b9050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b610d6e82610d686115fa565b836117cb565b610d788282611f45565b5050565b6000610dc5600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120c0565b9050919050565b610dfd7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610df86115fa565b610e9c565b610e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3390613d42565b60405180910390fd5b610e446120ce565b565b6000438210610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8190613bb2565b60405180910390fd5b610e95600b83611dc8565b9050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060058054610f1590613a40565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4190613a40565b8015610f8e5780601f10610f6357610100808354040283529160200191610f8e565b820191906000526020600020905b815481529060010190602001808311610f7157829003601f168201915b5050505050905090565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461108057600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826110349190613d62565b8154811061104557611044613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611083565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110bb6115fa565b905060006110c982866113d5565b90508381101561110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590613e37565b60405180910390fd5b61111b8286868403611602565b60019250505092915050565b6000806111326115fa565b905061113f818585611857565b600191505092915050565b8342111561118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118490613ea3565b60405180910390fd5b60006111ef6111e77fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111cc9493929190613ec3565b60405160208183030381529060405280519060200120612131565b85858561214b565b90506111fa81612176565b861461123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613f54565b60405180910390fd5b6112458188611f53565b50505050505050565b83421115611291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128890613fc0565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112c08c612176565b896040516020016112d696959493929190613fe0565b60405160208183030381529060405280519060200120905060006112f982612131565b905060006113098287878761214b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113709061408d565b60405180910390fd5b6113848a8a8a611602565b50505050505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6113bd82610934565b6113c681611ad9565b6113d08383611ce7565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6114886132b7565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106114df576114de613d96565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611671576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116689061411f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d7906141b1565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117be919061354a565b60405180910390a3505050565b60006117d784846113d5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118515781811015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183a9061421d565b60405180910390fd5b6118508484848403611602565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906142af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192c90614341565b60405180910390fd5b6119408383836121d4565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156119c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119be906143d3565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a5c9190613b32565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611ac0919061354a565b60405180910390a3611ad38484846121e4565b50505050565b611aea81611ae56115fa565b6121f4565b50565b611af78282610e9c565b611bc957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611b6e6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611c4957507f000000000000000000000000000000000000000000000000000000000000000046145b15611c76577f00000000000000000000000000000000000000000000000000000000000000009050611ce4565b611ce17f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612291565b90505b90565b611cf18282610e9c565b15611dc457600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611d696115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b81811015611e47576000611de982846122cb565b905084868281548110611dff57611dfe613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff161115611e3157809250611e41565b600181611e3e9190613b32565b91505b50611dd5565b60008214611ea95784600183611e5d9190613d62565b81548110611e6e57611e6d613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611eac565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b611edc6122f1565b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611f206115fa565b604051611f2d9190613725565b60405180910390a1565b611f41828261233a565b5050565b611f4f82826123c7565b5050565b6000611f5e83610c07565b90506000611f6b84610cef565b905082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46120678284836123e5565b50505050565b600063ffffffff80168211156120b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120af90614465565b60405180910390fd5b819050919050565b600081600001549050919050565b6120d66125de565b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861211a6115fa565b6040516121279190613725565b60405180910390a1565b600061214461213e611bcd565b83612628565b9050919050565b600080600061215c8787878761265b565b9150915061216981612767565b8192505050949350505050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506121c3816120c0565b91506121ce81612933565b50919050565b6121df838383612949565b505050565b6121ef838383612949565b505050565b6121fe8282610e9c565b61228d576122238173ffffffffffffffffffffffffffffffffffffffff1660146129a1565b6122318360001c60206129a1565b604051602001612242929190614559565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122849190613445565b60405180910390fd5b5050565b600083838346306040516020016122ac959493929190614593565b6040516020818303038152906040528051906020012090509392505050565b600060028284186122dc9190614615565b8284166122e99190613b32565b905092915050565b6122f9610c84565b612338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232f90614692565b60405180910390fd5b565b6123448282612bdd565b61234c612c47565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123726108fb565b11156123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123aa90614724565b60405180910390fd5b6123c1600b612c6b83612c81565b50505050565b6123d18282612ef9565b6123df600b6130d183612c81565b50505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156124215750600081115b156125d957600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146124ff576000806124a8600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206130d185612c81565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516124f4929190614744565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146125d857600080612581600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c6b85612c81565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516125cd929190614744565b60405180910390a250505b5b505050565b6125e6610c84565b15612626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261d906147b9565b60405180910390fd5b565b6000828260405160200161263d929190614846565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561269657600060039150915061275e565b601b8560ff16141580156126ae5750601c8560ff1614155b156126c057600060049150915061275e565b6000600187878787604051600081526020016040526040516126e5949392919061487d565b6020604051602081039080840390855afa158015612707573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127555760006001925092505061275e565b80600092509250505b94509492505050565b6000600481111561277b5761277a6148c2565b5b81600481111561278e5761278d6148c2565b5b031561293057600160048111156127a8576127a76148c2565b5b8160048111156127bb576127ba6148c2565b5b036127fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f29061493d565b60405180910390fd5b6002600481111561280f5761280e6148c2565b5b816004811115612822576128216148c2565b5b03612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149a9565b60405180910390fd5b60036004811115612876576128756148c2565b5b816004811115612889576128886148c2565b5b036128c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c090614a3b565b60405180910390fd5b6004808111156128dc576128db6148c2565b5b8160048111156128ef576128ee6148c2565b5b0361292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614acd565b60405180910390fd5b5b50565b6001816000016000828254019250508190555050565b6129548383836130e7565b61295c610c84565b1561299c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299390614b5f565b60405180910390fd5b505050565b6060600060028360026129b49190614b7f565b6129be9190613b32565b67ffffffffffffffff8111156129d7576129d6614bc1565b5b6040519080825280601f01601f191660200182016040528015612a095781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a4157612a40613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612aa557612aa4613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ae59190614b7f565b612aef9190613b32565b90505b6001811115612b8f577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b3157612b30613d96565b5b1a60f81b828281518110612b4857612b47613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612b8890614bf0565b9050612af2565b5060008414612bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bca90614c65565b60405180910390fd5b8091505092915050565b612be561097d565b81612bee6108fb565b612bf89190613b32565b1115612c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3090614cd1565b60405180910390fd5b612c4382826130ec565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008183612c799190613b32565b905092915050565b60008060008580549050905060008114612cef5785600182612ca39190613d62565b81548110612cb457612cb3613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612cf2565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612d2083858763ffffffff16565b9150600081118015612d7357504386600183612d3c9190613d62565b81548110612d4d57612d4c613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612e0057612d818261324c565b86600183612d8f9190613d62565b81548110612da057612d9f613d96565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612ef0565b856040518060400160405280612e154361206d565b63ffffffff168152602001612e298561324c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5f90614d63565b60405180910390fd5b612f74826000836121d4565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff290614df5565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008282546130539190613d62565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130b8919061354a565b60405180910390a36130cc836000846121e4565b505050565b600081836130df9190613d62565b905092915050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361315b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315290614e61565b60405180910390fd5b613167600083836121d4565b80600360008282546131799190613b32565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131cf9190613b32565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613234919061354a565b60405180910390a3613248600083836121e4565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156132af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a690614ef3565b60405180910390fd5b819050919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61332f816132fa565b811461333a57600080fd5b50565b60008135905061334c81613326565b92915050565b600060208284031215613368576133676132f5565b5b60006133768482850161333d565b91505092915050565b60008115159050919050565b6133948161337f565b82525050565b60006020820190506133af600083018461338b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133ef5780820151818401526020810190506133d4565b60008484015250505050565b6000601f19601f8301169050919050565b6000613417826133b5565b61342181856133c0565b93506134318185602086016133d1565b61343a816133fb565b840191505092915050565b6000602082019050818103600083015261345f818461340c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061349282613467565b9050919050565b6134a281613487565b81146134ad57600080fd5b50565b6000813590506134bf81613499565b92915050565b6000819050919050565b6134d8816134c5565b81146134e357600080fd5b50565b6000813590506134f5816134cf565b92915050565b60008060408385031215613512576135116132f5565b5b6000613520858286016134b0565b9250506020613531858286016134e6565b9150509250929050565b613544816134c5565b82525050565b600060208201905061355f600083018461353b565b92915050565b60008060006060848603121561357e5761357d6132f5565b5b600061358c868287016134b0565b935050602061359d868287016134b0565b92505060406135ae868287016134e6565b9150509250925092565b6000819050919050565b6135cb816135b8565b81146135d657600080fd5b50565b6000813590506135e8816135c2565b92915050565b600060208284031215613604576136036132f5565b5b6000613612848285016135d9565b91505092915050565b613624816135b8565b82525050565b600060208201905061363f600083018461361b565b92915050565b6000806040838503121561365c5761365b6132f5565b5b600061366a858286016135d9565b925050602061367b858286016134b0565b9150509250929050565b600060ff82169050919050565b61369b81613685565b82525050565b60006020820190506136b66000830184613692565b92915050565b6000602082840312156136d2576136d16132f5565b5b60006136e0848285016134e6565b91505092915050565b6000602082840312156136ff576136fe6132f5565b5b600061370d848285016134b0565b91505092915050565b61371f81613487565b82525050565b600060208201905061373a6000830184613716565b92915050565b600063ffffffff82169050919050565b61375981613740565b82525050565b60006020820190506137746000830184613750565b92915050565b61378381613685565b811461378e57600080fd5b50565b6000813590506137a08161377a565b92915050565b60008060008060008060c087890312156137c3576137c26132f5565b5b60006137d189828a016134b0565b96505060206137e289828a016134e6565b95505060406137f389828a016134e6565b945050606061380489828a01613791565b935050608061381589828a016135d9565b92505060a061382689828a016135d9565b9150509295509295509295565b600080600080600080600060e0888a031215613852576138516132f5565b5b60006138608a828b016134b0565b97505060206138718a828b016134b0565b96505060406138828a828b016134e6565b95505060606138938a828b016134e6565b94505060806138a48a828b01613791565b93505060a06138b58a828b016135d9565b92505060c06138c68a828b016135d9565b91505092959891949750929550565b600080604083850312156138ec576138eb6132f5565b5b60006138fa858286016134b0565b925050602061390b858286016134b0565b9150509250929050565b61391e81613740565b811461392957600080fd5b50565b60008135905061393b81613915565b92915050565b60008060408385031215613958576139576132f5565b5b6000613966858286016134b0565b92505060206139778582860161392c565b9150509250929050565b61398a81613740565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6139c181613990565b82525050565b6040820160008201516139dd6000850182613981565b5060208201516139f060208501826139b8565b50505050565b6000604082019050613a0b60008301846139c7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613a5857607f821691505b602082108103613a6b57613a6a613a11565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613acd602f836133c0565b9150613ad882613a71565b604082019050919050565b60006020820190508181036000830152613afc81613ac0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b3d826134c5565b9150613b48836134c5565b9250828201905080821115613b6057613b5f613b03565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613b9c601f836133c0565b9150613ba782613b66565b602082019050919050565b60006020820190508181036000830152613bcb81613b8f565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b6000613c2e6039836133c0565b9150613c3982613bd2565b604082019050919050565b60006020820190508181036000830152613c5d81613c21565b9050919050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000613c9a6015836133c0565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b6000613d2c6037836133c0565b9150613d3782613cd0565b604082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b6000613d6d826134c5565b9150613d78836134c5565b9250828203905081811115613d9057613d8f613b03565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613e216025836133c0565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613e8d601d836133c0565b9150613e9882613e57565b602082019050919050565b60006020820190508181036000830152613ebc81613e80565b9050919050565b6000608082019050613ed8600083018761361b565b613ee56020830186613716565b613ef2604083018561353b565b613eff606083018461353b565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b6000613f3e6019836133c0565b9150613f4982613f08565b602082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000613faa601d836133c0565b9150613fb582613f74565b602082019050919050565b60006020820190508181036000830152613fd981613f9d565b9050919050565b600060c082019050613ff5600083018961361b565b6140026020830188613716565b61400f6040830187613716565b61401c606083018661353b565b614029608083018561353b565b61403660a083018461353b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000614077601e836133c0565b915061408282614041565b602082019050919050565b600060208201905081810360008301526140a68161406a565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006141096024836133c0565b9150614114826140ad565b604082019050919050565b60006020820190508181036000830152614138816140fc565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061419b6022836133c0565b91506141a68261413f565b604082019050919050565b600060208201905081810360008301526141ca8161418e565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614207601d836133c0565b9150614212826141d1565b602082019050919050565b60006020820190508181036000830152614236816141fa565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006142996025836133c0565b91506142a48261423d565b604082019050919050565b600060208201905081810360008301526142c88161428c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061432b6023836133c0565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006143bd6026836133c0565b91506143c882614361565b604082019050919050565b600060208201905081810360008301526143ec816143b0565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b600061444f6026836133c0565b915061445a826143f3565b604082019050919050565b6000602082019050818103600083015261447e81614442565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006144c6601783614485565b91506144d182614490565b601782019050919050565b60006144e7826133b5565b6144f18185614485565b93506145018185602086016133d1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614543601183614485565b915061454e8261450d565b601182019050919050565b6000614564826144b9565b915061457082856144dc565b915061457b82614536565b915061458782846144dc565b91508190509392505050565b600060a0820190506145a8600083018861361b565b6145b5602083018761361b565b6145c2604083018661361b565b6145cf606083018561353b565b6145dc6080830184613716565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614620826134c5565b915061462b836134c5565b92508261463b5761463a6145e6565b5b828204905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061467c6014836133c0565b915061468782614646565b602082019050919050565b600060208201905081810360008301526146ab8161466f565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061470e6030836133c0565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b6000604082019050614759600083018561353b565b614766602083018461353b565b9392505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006147a36010836133c0565b91506147ae8261476d565b602082019050919050565b600060208201905081810360008301526147d281614796565b9050919050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061480f600283614485565b915061481a826147d9565b600282019050919050565b6000819050919050565b61484061483b826135b8565b614825565b82525050565b600061485182614802565b915061485d828561482f565b60208201915061486d828461482f565b6020820191508190509392505050565b6000608082019050614892600083018761361b565b61489f6020830186613692565b6148ac604083018561361b565b6148b9606083018461361b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006149276018836133c0565b9150614932826148f1565b602082019050919050565b600060208201905081810360008301526149568161491a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614993601f836133c0565b915061499e8261495d565b602082019050919050565b600060208201905081810360008301526149c281614986565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a256022836133c0565b9150614a30826149c9565b604082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ab76022836133c0565b9150614ac282614a5b565b604082019050919050565b60006020820190508181036000830152614ae681614aaa565b9050919050565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6000614b49602a836133c0565b9150614b5482614aed565b604082019050919050565b60006020820190508181036000830152614b7881614b3c565b9050919050565b6000614b8a826134c5565b9150614b95836134c5565b9250828202614ba3816134c5565b91508282048414831517614bba57614bb9613b03565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614bfb826134c5565b915060008203614c0e57614c0d613b03565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614c4f6020836133c0565b9150614c5a82614c19565b602082019050919050565b60006020820190508181036000830152614c7e81614c42565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b6000614cbb6019836133c0565b9150614cc682614c85565b602082019050919050565b60006020820190508181036000830152614cea81614cae565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d4d6021836133c0565b9150614d5882614cf1565b604082019050919050565b60006020820190508181036000830152614d7c81614d40565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ddf6022836133c0565b9150614dea82614d83565b604082019050919050565b60006020820190508181036000830152614e0e81614dd2565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614e4b601f836133c0565b9150614e5682614e15565b602082019050919050565b60006020820190508181036000830152614e7a81614e3e565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614edd6027836133c0565b9150614ee882614e81565b604082019050919050565b60006020820190508181036000830152614f0c81614ed0565b905091905056fea2646970667358221220fc046de338956e8aeca6864c04e8d3abc0bfe16b1e4bab5dd46bfa48e925c06564736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b578063a217fddf116100b8578063d53913931161007c578063d539139314610714578063d547741f14610732578063dd62ed3e1461074e578063e63ab1e91461077e578063f1127ed81461079c5761023d565b8063a217fddf1461065e578063a457c2d71461067c578063a9059cbb146106ac578063c3cda520146106dc578063d505accf146106f85761023d565b80638456cb59116100ff5780638456cb59146105a65780638e539e8c146105b057806391d14854146105e057806395d89b41146106105780639ab24eb01461062e5761023d565b80636fcfff45146104dc57806370a082311461050c57806375b238fc1461053c57806379cc67901461055a5780637ecebe00146105765761023d565b80633644e515116101c957806340c10f191161018d57806340c10f191461043a57806342966c6814610456578063587cde1e146104725780635c19a95c146104a25780635c975abb146104be5761023d565b80633644e5151461039657806336568abe146103b457806339509351146103d05780633a46b1a8146104005780633f4ba83a146104305761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a578063355274ea146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613352565b6107cc565b604051610269919061339a565b60405180910390f35b61027a610846565b6040516102879190613445565b60405180910390f35b6102aa60048036038101906102a591906134fb565b6108d8565b6040516102b7919061339a565b60405180910390f35b6102c86108fb565b6040516102d5919061354a565b60405180910390f35b6102f860048036038101906102f39190613565565b610905565b604051610305919061339a565b60405180910390f35b610328600480360381019061032391906135ee565b610934565b604051610335919061362a565b60405180910390f35b61035860048036038101906103539190613645565b610953565b005b610362610974565b60405161036f91906136a1565b60405180910390f35b61038061097d565b60405161038d919061354a565b60405180910390f35b61039e6109a5565b6040516103ab919061362a565b60405180910390f35b6103ce60048036038101906103c99190613645565b6109b4565b005b6103ea60048036038101906103e591906134fb565b610a37565b6040516103f7919061339a565b60405180910390f35b61041a600480360381019061041591906134fb565b610a6e565b604051610427919061354a565b60405180910390f35b610438610b02565b005b610454600480360381019061044f91906134fb565b610b7c565b005b610470600480360381019061046b91906136bc565b610bf3565b005b61048c600480360381019061048791906136e9565b610c07565b6040516104999190613725565b60405180910390f35b6104bc60048036038101906104b791906136e9565b610c70565b005b6104c6610c84565b6040516104d3919061339a565b60405180910390f35b6104f660048036038101906104f191906136e9565b610c9b565b604051610503919061375f565b60405180910390f35b610526600480360381019061052191906136e9565b610cef565b604051610533919061354a565b60405180910390f35b610544610d38565b604051610551919061362a565b60405180910390f35b610574600480360381019061056f91906134fb565b610d5c565b005b610590600480360381019061058b91906136e9565b610d7c565b60405161059d919061354a565b60405180910390f35b6105ae610dcc565b005b6105ca60048036038101906105c591906136bc565b610e46565b6040516105d7919061354a565b60405180910390f35b6105fa60048036038101906105f59190613645565b610e9c565b604051610607919061339a565b60405180910390f35b610618610f06565b6040516106259190613445565b60405180910390f35b610648600480360381019061064391906136e9565b610f98565b604051610655919061354a565b60405180910390f35b6106666110a9565b604051610673919061362a565b60405180910390f35b610696600480360381019061069191906134fb565b6110b0565b6040516106a3919061339a565b60405180910390f35b6106c660048036038101906106c191906134fb565b611127565b6040516106d3919061339a565b60405180910390f35b6106f660048036038101906106f191906137a6565b61114a565b005b610712600480360381019061070d9190613833565b61124e565b005b61071c611390565b604051610729919061362a565b60405180910390f35b61074c60048036038101906107479190613645565b6113b4565b005b610768600480360381019061076391906138d5565b6113d5565b604051610775919061354a565b60405180910390f35b61078661145c565b604051610793919061362a565b60405180910390f35b6107b660048036038101906107b19190613941565b611480565b6040516107c391906139f6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083f575061083e82611590565b5b9050919050565b60606004805461085590613a40565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613a40565b80156108ce5780601f106108a3576101008083540402835291602001916108ce565b820191906000526020600020905b8154815290600101906020018083116108b157829003601f168201915b5050505050905090565b6000806108e36115fa565b90506108f0818585611602565b600191505092915050565b6000600354905090565b6000806109106115fa565b905061091d8582856117cb565b610928858585611857565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61095c82610934565b61096581611ad9565b61096f8383611aed565b505050565b60006012905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60006109af611bcd565b905090565b6109bc6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2090613ae3565b60405180910390fd5b610a338282611ce7565b5050565b600080610a426115fa565b9050610a63818585610a5485896113d5565b610a5e9190613b32565b611602565b600191505092915050565b6000438210610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990613bb2565b60405180910390fd5b610afa600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083611dc8565b905092915050565b610b337f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b2e6115fa565b610e9c565b610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613c44565b60405180910390fd5b610b7a611ed4565b565b610ba67ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc933610e9c565b610be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdc90613cb0565b60405180910390fd5b610bef8282611f37565b5050565b610c04610bfe6115fa565b82611f45565b50565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6115fa565b82611f53565b50565b6000600660009054906101000a900460ff16905090565b6000610ce8600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061206d565b9050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b610d6e82610d686115fa565b836117cb565b610d788282611f45565b5050565b6000610dc5600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120c0565b9050919050565b610dfd7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610df86115fa565b610e9c565b610e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3390613d42565b60405180910390fd5b610e446120ce565b565b6000438210610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8190613bb2565b60405180910390fd5b610e95600b83611dc8565b9050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060058054610f1590613a40565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4190613a40565b8015610f8e5780601f10610f6357610100808354040283529160200191610f8e565b820191906000526020600020905b815481529060010190602001808311610f7157829003601f168201915b5050505050905090565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461108057600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826110349190613d62565b8154811061104557611044613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611083565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110bb6115fa565b905060006110c982866113d5565b90508381101561110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590613e37565b60405180910390fd5b61111b8286868403611602565b60019250505092915050565b6000806111326115fa565b905061113f818585611857565b600191505092915050565b8342111561118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118490613ea3565b60405180910390fd5b60006111ef6111e77fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111cc9493929190613ec3565b60405160208183030381529060405280519060200120612131565b85858561214b565b90506111fa81612176565b861461123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613f54565b60405180910390fd5b6112458188611f53565b50505050505050565b83421115611291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128890613fc0565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112c08c612176565b896040516020016112d696959493929190613fe0565b60405160208183030381529060405280519060200120905060006112f982612131565b905060006113098287878761214b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113709061408d565b60405180910390fd5b6113848a8a8a611602565b50505050505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6113bd82610934565b6113c681611ad9565b6113d08383611ce7565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6114886132b7565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106114df576114de613d96565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611671576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116689061411f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d7906141b1565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117be919061354a565b60405180910390a3505050565b60006117d784846113d5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118515781811015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183a9061421d565b60405180910390fd5b6118508484848403611602565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906142af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192c90614341565b60405180910390fd5b6119408383836121d4565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156119c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119be906143d3565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a5c9190613b32565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611ac0919061354a565b60405180910390a3611ad38484846121e4565b50505050565b611aea81611ae56115fa565b6121f4565b50565b611af78282610e9c565b611bc957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611b6e6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611c4957507f000000000000000000000000000000000000000000000000000000000000000046145b15611c76577f00000000000000000000000000000000000000000000000000000000000000009050611ce4565b611ce17f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612291565b90505b90565b611cf18282610e9c565b15611dc457600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611d696115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b81811015611e47576000611de982846122cb565b905084868281548110611dff57611dfe613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff161115611e3157809250611e41565b600181611e3e9190613b32565b91505b50611dd5565b60008214611ea95784600183611e5d9190613d62565b81548110611e6e57611e6d613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611eac565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b611edc6122f1565b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611f206115fa565b604051611f2d9190613725565b60405180910390a1565b611f41828261233a565b5050565b611f4f82826123c7565b5050565b6000611f5e83610c07565b90506000611f6b84610cef565b905082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46120678284836123e5565b50505050565b600063ffffffff80168211156120b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120af90614465565b60405180910390fd5b819050919050565b600081600001549050919050565b6120d66125de565b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861211a6115fa565b6040516121279190613725565b60405180910390a1565b600061214461213e611bcd565b83612628565b9050919050565b600080600061215c8787878761265b565b9150915061216981612767565b8192505050949350505050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506121c3816120c0565b91506121ce81612933565b50919050565b6121df838383612949565b505050565b6121ef838383612949565b505050565b6121fe8282610e9c565b61228d576122238173ffffffffffffffffffffffffffffffffffffffff1660146129a1565b6122318360001c60206129a1565b604051602001612242929190614559565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122849190613445565b60405180910390fd5b5050565b600083838346306040516020016122ac959493929190614593565b6040516020818303038152906040528051906020012090509392505050565b600060028284186122dc9190614615565b8284166122e99190613b32565b905092915050565b6122f9610c84565b612338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232f90614692565b60405180910390fd5b565b6123448282612bdd565b61234c612c47565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123726108fb565b11156123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123aa90614724565b60405180910390fd5b6123c1600b612c6b83612c81565b50505050565b6123d18282612ef9565b6123df600b6130d183612c81565b50505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156124215750600081115b156125d957600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146124ff576000806124a8600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206130d185612c81565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516124f4929190614744565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146125d857600080612581600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c6b85612c81565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516125cd929190614744565b60405180910390a250505b5b505050565b6125e6610c84565b15612626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261d906147b9565b60405180910390fd5b565b6000828260405160200161263d929190614846565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561269657600060039150915061275e565b601b8560ff16141580156126ae5750601c8560ff1614155b156126c057600060049150915061275e565b6000600187878787604051600081526020016040526040516126e5949392919061487d565b6020604051602081039080840390855afa158015612707573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127555760006001925092505061275e565b80600092509250505b94509492505050565b6000600481111561277b5761277a6148c2565b5b81600481111561278e5761278d6148c2565b5b031561293057600160048111156127a8576127a76148c2565b5b8160048111156127bb576127ba6148c2565b5b036127fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f29061493d565b60405180910390fd5b6002600481111561280f5761280e6148c2565b5b816004811115612822576128216148c2565b5b03612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149a9565b60405180910390fd5b60036004811115612876576128756148c2565b5b816004811115612889576128886148c2565b5b036128c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c090614a3b565b60405180910390fd5b6004808111156128dc576128db6148c2565b5b8160048111156128ef576128ee6148c2565b5b0361292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614acd565b60405180910390fd5b5b50565b6001816000016000828254019250508190555050565b6129548383836130e7565b61295c610c84565b1561299c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299390614b5f565b60405180910390fd5b505050565b6060600060028360026129b49190614b7f565b6129be9190613b32565b67ffffffffffffffff8111156129d7576129d6614bc1565b5b6040519080825280601f01601f191660200182016040528015612a095781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a4157612a40613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612aa557612aa4613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ae59190614b7f565b612aef9190613b32565b90505b6001811115612b8f577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b3157612b30613d96565b5b1a60f81b828281518110612b4857612b47613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612b8890614bf0565b9050612af2565b5060008414612bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bca90614c65565b60405180910390fd5b8091505092915050565b612be561097d565b81612bee6108fb565b612bf89190613b32565b1115612c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3090614cd1565b60405180910390fd5b612c4382826130ec565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008183612c799190613b32565b905092915050565b60008060008580549050905060008114612cef5785600182612ca39190613d62565b81548110612cb457612cb3613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612cf2565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612d2083858763ffffffff16565b9150600081118015612d7357504386600183612d3c9190613d62565b81548110612d4d57612d4c613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612e0057612d818261324c565b86600183612d8f9190613d62565b81548110612da057612d9f613d96565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612ef0565b856040518060400160405280612e154361206d565b63ffffffff168152602001612e298561324c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5f90614d63565b60405180910390fd5b612f74826000836121d4565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff290614df5565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008282546130539190613d62565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130b8919061354a565b60405180910390a36130cc836000846121e4565b505050565b600081836130df9190613d62565b905092915050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361315b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315290614e61565b60405180910390fd5b613167600083836121d4565b80600360008282546131799190613b32565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131cf9190613b32565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613234919061354a565b60405180910390a3613248600083836121e4565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156132af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a690614ef3565b60405180910390fd5b819050919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61332f816132fa565b811461333a57600080fd5b50565b60008135905061334c81613326565b92915050565b600060208284031215613368576133676132f5565b5b60006133768482850161333d565b91505092915050565b60008115159050919050565b6133948161337f565b82525050565b60006020820190506133af600083018461338b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133ef5780820151818401526020810190506133d4565b60008484015250505050565b6000601f19601f8301169050919050565b6000613417826133b5565b61342181856133c0565b93506134318185602086016133d1565b61343a816133fb565b840191505092915050565b6000602082019050818103600083015261345f818461340c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061349282613467565b9050919050565b6134a281613487565b81146134ad57600080fd5b50565b6000813590506134bf81613499565b92915050565b6000819050919050565b6134d8816134c5565b81146134e357600080fd5b50565b6000813590506134f5816134cf565b92915050565b60008060408385031215613512576135116132f5565b5b6000613520858286016134b0565b9250506020613531858286016134e6565b9150509250929050565b613544816134c5565b82525050565b600060208201905061355f600083018461353b565b92915050565b60008060006060848603121561357e5761357d6132f5565b5b600061358c868287016134b0565b935050602061359d868287016134b0565b92505060406135ae868287016134e6565b9150509250925092565b6000819050919050565b6135cb816135b8565b81146135d657600080fd5b50565b6000813590506135e8816135c2565b92915050565b600060208284031215613604576136036132f5565b5b6000613612848285016135d9565b91505092915050565b613624816135b8565b82525050565b600060208201905061363f600083018461361b565b92915050565b6000806040838503121561365c5761365b6132f5565b5b600061366a858286016135d9565b925050602061367b858286016134b0565b9150509250929050565b600060ff82169050919050565b61369b81613685565b82525050565b60006020820190506136b66000830184613692565b92915050565b6000602082840312156136d2576136d16132f5565b5b60006136e0848285016134e6565b91505092915050565b6000602082840312156136ff576136fe6132f5565b5b600061370d848285016134b0565b91505092915050565b61371f81613487565b82525050565b600060208201905061373a6000830184613716565b92915050565b600063ffffffff82169050919050565b61375981613740565b82525050565b60006020820190506137746000830184613750565b92915050565b61378381613685565b811461378e57600080fd5b50565b6000813590506137a08161377a565b92915050565b60008060008060008060c087890312156137c3576137c26132f5565b5b60006137d189828a016134b0565b96505060206137e289828a016134e6565b95505060406137f389828a016134e6565b945050606061380489828a01613791565b935050608061381589828a016135d9565b92505060a061382689828a016135d9565b9150509295509295509295565b600080600080600080600060e0888a031215613852576138516132f5565b5b60006138608a828b016134b0565b97505060206138718a828b016134b0565b96505060406138828a828b016134e6565b95505060606138938a828b016134e6565b94505060806138a48a828b01613791565b93505060a06138b58a828b016135d9565b92505060c06138c68a828b016135d9565b91505092959891949750929550565b600080604083850312156138ec576138eb6132f5565b5b60006138fa858286016134b0565b925050602061390b858286016134b0565b9150509250929050565b61391e81613740565b811461392957600080fd5b50565b60008135905061393b81613915565b92915050565b60008060408385031215613958576139576132f5565b5b6000613966858286016134b0565b92505060206139778582860161392c565b9150509250929050565b61398a81613740565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6139c181613990565b82525050565b6040820160008201516139dd6000850182613981565b5060208201516139f060208501826139b8565b50505050565b6000604082019050613a0b60008301846139c7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613a5857607f821691505b602082108103613a6b57613a6a613a11565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613acd602f836133c0565b9150613ad882613a71565b604082019050919050565b60006020820190508181036000830152613afc81613ac0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b3d826134c5565b9150613b48836134c5565b9250828201905080821115613b6057613b5f613b03565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613b9c601f836133c0565b9150613ba782613b66565b602082019050919050565b60006020820190508181036000830152613bcb81613b8f565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b6000613c2e6039836133c0565b9150613c3982613bd2565b604082019050919050565b60006020820190508181036000830152613c5d81613c21565b9050919050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000613c9a6015836133c0565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b6000613d2c6037836133c0565b9150613d3782613cd0565b604082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b6000613d6d826134c5565b9150613d78836134c5565b9250828203905081811115613d9057613d8f613b03565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613e216025836133c0565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613e8d601d836133c0565b9150613e9882613e57565b602082019050919050565b60006020820190508181036000830152613ebc81613e80565b9050919050565b6000608082019050613ed8600083018761361b565b613ee56020830186613716565b613ef2604083018561353b565b613eff606083018461353b565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b6000613f3e6019836133c0565b9150613f4982613f08565b602082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000613faa601d836133c0565b9150613fb582613f74565b602082019050919050565b60006020820190508181036000830152613fd981613f9d565b9050919050565b600060c082019050613ff5600083018961361b565b6140026020830188613716565b61400f6040830187613716565b61401c606083018661353b565b614029608083018561353b565b61403660a083018461353b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000614077601e836133c0565b915061408282614041565b602082019050919050565b600060208201905081810360008301526140a68161406a565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006141096024836133c0565b9150614114826140ad565b604082019050919050565b60006020820190508181036000830152614138816140fc565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061419b6022836133c0565b91506141a68261413f565b604082019050919050565b600060208201905081810360008301526141ca8161418e565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614207601d836133c0565b9150614212826141d1565b602082019050919050565b60006020820190508181036000830152614236816141fa565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006142996025836133c0565b91506142a48261423d565b604082019050919050565b600060208201905081810360008301526142c88161428c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061432b6023836133c0565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006143bd6026836133c0565b91506143c882614361565b604082019050919050565b600060208201905081810360008301526143ec816143b0565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b600061444f6026836133c0565b915061445a826143f3565b604082019050919050565b6000602082019050818103600083015261447e81614442565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006144c6601783614485565b91506144d182614490565b601782019050919050565b60006144e7826133b5565b6144f18185614485565b93506145018185602086016133d1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614543601183614485565b915061454e8261450d565b601182019050919050565b6000614564826144b9565b915061457082856144dc565b915061457b82614536565b915061458782846144dc565b91508190509392505050565b600060a0820190506145a8600083018861361b565b6145b5602083018761361b565b6145c2604083018661361b565b6145cf606083018561353b565b6145dc6080830184613716565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614620826134c5565b915061462b836134c5565b92508261463b5761463a6145e6565b5b828204905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061467c6014836133c0565b915061468782614646565b602082019050919050565b600060208201905081810360008301526146ab8161466f565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061470e6030836133c0565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b6000604082019050614759600083018561353b565b614766602083018461353b565b9392505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006147a36010836133c0565b91506147ae8261476d565b602082019050919050565b600060208201905081810360008301526147d281614796565b9050919050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061480f600283614485565b915061481a826147d9565b600282019050919050565b6000819050919050565b61484061483b826135b8565b614825565b82525050565b600061485182614802565b915061485d828561482f565b60208201915061486d828461482f565b6020820191508190509392505050565b6000608082019050614892600083018761361b565b61489f6020830186613692565b6148ac604083018561361b565b6148b9606083018461361b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006149276018836133c0565b9150614932826148f1565b602082019050919050565b600060208201905081810360008301526149568161491a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614993601f836133c0565b915061499e8261495d565b602082019050919050565b600060208201905081810360008301526149c281614986565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a256022836133c0565b9150614a30826149c9565b604082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ab76022836133c0565b9150614ac282614a5b565b604082019050919050565b60006020820190508181036000830152614ae681614aaa565b9050919050565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6000614b49602a836133c0565b9150614b5482614aed565b604082019050919050565b60006020820190508181036000830152614b7881614b3c565b9050919050565b6000614b8a826134c5565b9150614b95836134c5565b9250828202614ba3816134c5565b91508282048414831517614bba57614bb9613b03565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614bfb826134c5565b915060008203614c0e57614c0d613b03565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614c4f6020836133c0565b9150614c5a82614c19565b602082019050919050565b60006020820190508181036000830152614c7e81614c42565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b6000614cbb6019836133c0565b9150614cc682614c85565b602082019050919050565b60006020820190508181036000830152614cea81614cae565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d4d6021836133c0565b9150614d5882614cf1565b604082019050919050565b60006020820190508181036000830152614d7c81614d40565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ddf6022836133c0565b9150614dea82614d83565b604082019050919050565b60006020820190508181036000830152614e0e81614dd2565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614e4b601f836133c0565b9150614e5682614e15565b602082019050919050565b60006020820190508181036000830152614e7a81614e3e565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614edd6027836133c0565b9150614ee882614e81565b604082019050919050565b60006020820190508181036000830152614f0c81614ed0565b905091905056fea2646970667358221220fc046de338956e8aeca6864c04e8d3abc0bfe16b1e4bab5dd46bfa48e925c06564736f6c63430008110033","abi":[{"inputs":[{"internalType":"uint256","name":"cap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ADMIN_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":"DOMAIN_SEPARATOR","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":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/Multisender.json b/deployments/littestnet_987/Multisender.json deleted file mode 100644 index 261efd5..0000000 --- a/deployments/littestnet_987/Multisender.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Multisender.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// This contract does one thing, simply. it allows you to send eth or tokens to multiple recipients. Useful for setting up a testnet and funding all the validators and stakers.\\n\\ncontract Multisender is Ownable {\\n function sendEth(address[] calldata _recipients) public payable {\\n uint256 val = msg.value / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n payable(_recipients[i]).transfer(val);\\n }\\n }\\n\\n function sendTokens(address[] calldata _recipients, address tokenContract)\\n public\\n {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n uint256 val = bal / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n tkn.transfer(_recipients[i], val);\\n }\\n }\\n\\n function withdraw() public onlyOwner {\\n payable(msg.sender).transfer(address(this).balance);\\n }\\n\\n function withdrawTokens(address tokenContract) public onlyOwner {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n tkn.transfer(msg.sender, bal);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xFc3278e256BB6a37E2406C6Efb8093A4EaC4e341","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610bf98061010d6000396000f3fe6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","abi":[{"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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"sendEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"address","name":"tokenContract","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/PKPNFTMetadata.json b/deployments/littestnet_987/PKPNFTMetadata.json deleted file mode 100644 index 27c2623..0000000 --- a/deployments/littestnet_987/PKPNFTMetadata.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x67cDA628B859526B6bCC5A20317517e4DF3AA7Fe","bytecode":"0x608060405234801561001057600080fd5b506117de806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"buffer","type":"bytes"}],"name":"bytesToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"address","name":"ethAddress","type":"address"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/PKPPermissions.json b/deployments/littestnet_987/PKPPermissions.json deleted file mode 100644 index 6236b63..0000000 --- a/deployments/littestnet_987/PKPPermissions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xCA73fe5696e61387159BcDF895663d88Bd215FdF","bytecode":"0x60806040523480156200001157600080fd5b5060405162005087380380620050878339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b614e7080620002176000396000f3fe608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea264697066735822122089097a4127d577d3fae3fe286029bc47b68316fba379f60c9057a944d30d1a8664736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea264697066735822122089097a4127d577d3fae3fe286029bc47b68316fba379f60c9057a944d30d1a8664736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"userPubkey","type":"bytes"}],"name":"PermittedAuthMethodAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"}],"name":"PermittedAuthMethodRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"group","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootHashUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod","name":"authMethod","type":"tuple"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"addPermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"authMethods","outputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getAuthMethodId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedActions","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"maxScopeId","type":"uint256"}],"name":"getPermittedAuthMethodScopes","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAuthMethods","outputs":[{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getTokenIdsForAuthMethod","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getUserPubkeyForAuthMethod","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"isPermittedAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isPermittedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"isPermittedAuthMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"isPermittedAuthMethodScopePresent","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"removePermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"removePermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"removePermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"removePermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verifyState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool[]","name":"proofFlags","type":"bool[]"},{"internalType":"bytes32[]","name":"leaves","type":"bytes32[]"}],"name":"verifyStates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/RateLimitNFT.json b/deployments/littestnet_987/RateLimitNFT.json deleted file mode 100644 index c7ea5f9..0000000 --- a/deployments/littestnet_987/RateLimitNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/RateLimitNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Rate Limit NFT\\n///\\n/// @dev This is the contract for the Rate Limit NFTs\\n/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit\\n/// And how it works, is that you can buy X requestsPerKilosecond over a period of time\\n/// 1 requestsPerKilosecond = 0.001 requests per second and\\n/// 1000 requestsPerKilosecond = 1 request per second\\ncontract RateLimitNFT is\\n ERC721(\\\"Rate Limit Increases on Lit Protocol\\\", \\\"RLI\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using Strings for uint256;\\n /* ========== STATE VARIABLES ========== */\\n\\n address public freeMintSigner;\\n uint256 public additionalRequestsPerKilosecondCost;\\n uint256 public tokenIdCounter;\\n uint256 public defaultRateLimitWindowSeconds = 60 * 60; // 60 mins\\n uint256 public RLIHolderRateLimitWindowSeconds = 5 * 60; // 5 mins\\n uint256 public freeRequestsPerRateLimitWindow = 10;\\n\\n mapping(uint256 => RateLimit) public capacity;\\n mapping(bytes32 => bool) public redeemedFreeMints;\\n\\n struct RateLimit {\\n uint256 requestsPerKilosecond;\\n uint256 expiresAt;\\n }\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n // make sure the msgHash matches the tokenId\\n // if these don't match, the user could use any old signature\\n // to mint any number of PKPs\\n // and this would be vulnerable to replay attacks\\n // FIXME this needs the whole \\\"ethereum signed message: \\\\27\\\" thingy prepended to actually work\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // make sure it hasn't already been redeemed\\n require(\\n !redeemedFreeMints[msgHash],\\n \\\"This freeMint has already been redeemed. How embarassing.\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function calculateCost(\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n require(\\n requestsPerKilosecond > 0,\\n \\\"The requestsPerKilosecond must be greater than 0\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n\\n // calculate the cost\\n uint256 cost = (requestsPerKilosecond *\\n durationInSeconds *\\n additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return cost;\\n }\\n\\n function calculateRequestsPerKilosecond(\\n uint256 payingAmount,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n // console.log(\\\"durationInSeconds: \\\");\\n // console.log(durationInSeconds);\\n\\n // calculate the cost\\n uint256 requestsPerKilosecond = payingAmount /\\n ((durationInSeconds * additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return requestsPerKilosecond;\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit Protocol Rate Limit Increase\\\", \\\"description\\\": \\\"This NFT entitles the holder to a rate limit increase on the Lit Protocol Network\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"display_type\\\": \\\"date\\\", \\\"trait_type\\\": \\\"Expiration Date\\\", \\\"value\\\": ',\\n capacity[tokenId].expiresAt.toString(),\\n '}, {\\\"display_type\\\": \\\"number\\\", \\\"trait_type\\\": \\\"Millirequests Per Second\\\", \\\"value\\\": ',\\n capacity[tokenId].requestsPerKilosecond.toString(),\\n \\\"}]}\\\"\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n\\n function isExpired(uint256 tokenId) public view returns (bool) {\\n return capacity[tokenId].expiresAt <= block.timestamp;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function.\\n function mint(uint256 expiresAt) public payable returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n uint256 requestsPerKilosecond = calculateRequestsPerKilosecond(\\n msg.value,\\n expiresAt\\n );\\n\\n // sanity check\\n uint256 cost = calculateCost(requestsPerKilosecond, expiresAt);\\n\\n require(\\n msg.value > 0 && msg.value >= cost,\\n \\\"You must send the cost of this rate limit increase. To check the cost, use the calculateCost function.\\\"\\n );\\n require(cost > 0, \\\"The cost must be greater than 0\\\");\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function freeMint(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(expiresAt, requestsPerKilosecond, msgHash, v, r, s);\\n redeemedFreeMints[msgHash] = true;\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n uint256 tokenId,\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) internal {\\n _safeMint(msg.sender, tokenId);\\n capacity[tokenId] = RateLimit(requestsPerKilosecond, expiresAt);\\n }\\n\\n function setAdditionalRequestsPerKilosecondCost(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n ) public onlyOwner {\\n additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost;\\n emit AdditionalRequestsPerKilosecondCostSet(\\n newAdditionalRequestsPerKilosecondCost\\n );\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n function setRateLimitWindowSeconds(\\n uint256 newRateLimitWindowSeconds\\n ) public onlyOwner {\\n defaultRateLimitWindowSeconds = newRateLimitWindowSeconds;\\n emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds);\\n }\\n\\n function setRLIHolderRateLimitWindowSeconds(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n ) public onlyOwner {\\n RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds;\\n emit RLIHolderRateLimitWindowSecondsSet(\\n newRLIHolderRateLimitWindowSeconds\\n );\\n }\\n\\n function setFreeRequestsPerRateLimitWindow(\\n uint256 newFreeRequestsPerRateLimitWindow\\n ) public onlyOwner {\\n freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow;\\n emit FreeRequestsPerRateLimitWindowSet(\\n newFreeRequestsPerRateLimitWindow\\n );\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event AdditionalRequestsPerKilosecondCostSet(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n );\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds);\\n event RLIHolderRateLimitWindowSecondsSet(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n );\\n event FreeRequestsPerRateLimitWindowSet(\\n uint256 newFreeRequestsPerRateLimitWindow\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x6F2c1225fE5cA5aeDe459eF5c508dcd0473814f5","bytecode":"0x6080604052610e10600f5561012c601055600a6011553480156200002257600080fd5b50604051806060016040528060248152602001620055f8602491396040518060400160405280600381526020017f524c490000000000000000000000000000000000000000000000000000000000815250816000908162000084919062000419565b50806001908162000096919062000419565b505050620000b9620000ad620000d160201b60201c565b620000d960201b60201c565b6001600b81905550620f4240600d8190555062000500565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200022157607f821691505b602082108103620002375762000236620001d9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000262565b620002ad868362000262565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002fa620002f4620002ee84620002c5565b620002cf565b620002c5565b9050919050565b6000819050919050565b6200031683620002d9565b6200032e620003258262000301565b8484546200026f565b825550505050565b600090565b6200034562000336565b620003528184846200030b565b505050565b5b818110156200037a576200036e6000826200033b565b60018101905062000358565b5050565b601f821115620003c95762000393816200023d565b6200039e8462000252565b81016020851015620003ae578190505b620003c6620003bd8562000252565b83018262000357565b50505b505050565b600082821c905092915050565b6000620003ee60001984600802620003ce565b1980831691505092915050565b6000620004098383620003db565b9150826002028217905092915050565b62000424826200019f565b67ffffffffffffffff81111562000440576200043f620001aa565b5b6200044c825462000208565b620004598282856200037e565b600060209050601f8311600181146200049157600084156200047c578287015190505b620004888582620003fb565b865550620004f8565b601f198416620004a1866200023d565b60005b82811015620004cb57848901518255600182019150602085019450602081019050620004a4565b86831015620004eb5784890151620004e7601f891682620003db565b8355505b6001600288020188555050505b505050505050565b6150e880620005106000396000f3fe6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c6343000811003352617465204c696d697420496e63726561736573206f6e204c69742050726f746f636f6c","deployedBytecode":"0x6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"AdditionalRequestsPerKilosecondCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"FreeRequestsPerRateLimitWindowSet","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":false,"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"RLIHolderRateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"RateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"RLIHolderRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalRequestsPerKilosecondCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payingAmount","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateRequestsPerKilosecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capacity","outputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeRequestsPerRateLimitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"isExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"redeemedFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"setAdditionalRequestsPerKilosecondCost","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"setFreeRequestsPerRateLimitWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"setRLIHolderRateLimitWindowSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"setRateLimitWindowSeconds","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/SoloNetPKP.json b/deployments/littestnet_987/SoloNetPKP.json deleted file mode 100644 index 74c3489..0000000 --- a/deployments/littestnet_987/SoloNetPKP.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0xd22bC8b91Ef0582D8E9F0BE0c7C21Dd97c1a0785","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000559565b508060019081620000a1919062000559565b505050620000c4620000b86200013c60201b60201c565b6200014460201b60201c565b6001600b81905550655af3107a4000600e8190555033600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001353360116200020a60201b6200240d1790919060201c565b5062000640565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006200023a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200024260201b60201c565b905092915050565b6000620002568383620002bc60201b60201c565b620002b1578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050620002b6565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200036157607f821691505b60208210810362000377576200037662000319565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003a2565b620003ed8683620003a2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200043a620004346200042e8462000405565b6200040f565b62000405565b9050919050565b6000819050919050565b620004568362000419565b6200046e620004658262000441565b848454620003af565b825550505050565b600090565b6200048562000476565b620004928184846200044b565b505050565b5b81811015620004ba57620004ae6000826200047b565b60018101905062000498565b5050565b601f8211156200050957620004d3816200037d565b620004de8462000392565b81016020851015620004ee578190505b62000506620004fd8562000392565b83018262000497565b50505b505050565b600082821c905092915050565b60006200052e600019846008026200050e565b1980831691505092915050565b60006200054983836200051b565b9150826002028217905092915050565b6200056482620002df565b67ffffffffffffffff81111562000580576200057f620002ea565b5b6200058c825462000348565b62000599828285620004be565b600060209050601f831160018114620005d15760008415620005bc578287015190505b620005c885826200053b565b86555062000638565b601f198416620005e1866200037d565b60005b828110156200060b57848901518255600182019150602085019450602081019050620005e4565b868310156200062b578489015162000627601f8916826200051b565b8355505b6001600288020188555050505b505050505050565b61598b80620006506000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea26469706673582212208e8b692426e477e74ad771c1bd1508002a9068ed832b1b80b7cc7f5a5f87d08d64736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea26469706673582212208e8b692426e477e74ad771c1bd1508002a9068ed832b1b80b7cc7f5a5f87d08d64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterPermitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRevoked","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingAddress","type":"address"}],"name":"StakingAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"_getTokenIdToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"addPermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"removePermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/SoloNetPKPHelper.json b/deployments/littestnet_987/SoloNetPKPHelper.json deleted file mode 100644 index c4079b7..0000000 --- a/deployments/littestnet_987/SoloNetPKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { SoloNetPKP } from \\\"./SoloNetPKP.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/// @title PKP Helper Contract\\n///\\n/// @dev This is the contract that helps minting PKPs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n SoloNetPKP public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = SoloNetPKP(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintAndAddAuthMethods(\\n bytes memory pubkey,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintAndAddAuthMethodsWithTypes(\\n pubkey,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintAndAddAuthMethodsWithTypes(\\n bytes memory pubkey,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpNFT.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = SoloNetPKP(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0xE393BCD2a9099C903D28949Bac2C4cEd21E55415","bytecode":"0x60806040523480156200001157600080fd5b506040516200254d3803806200254d833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b6122df806200026e6000396000f3fe6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220065b53c6419204fc11f6384f21b10b5337f803e0bb067285cbd8488fa305dab464736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220065b53c6419204fc11f6384f21b10b5337f803e0bb067285cbd8488fa305dab464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract SoloNetPKP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/littestnet_987/Staking.json b/deployments/littestnet_987/Staking.json deleted file mode 100644 index c5238d3..0000000 --- a/deployments/littestnet_987/Staking.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x22A9B25389030263f497C3989Df0263Ed16dedaB","bytecode":"0x60806040526000600160156101000a81548160ff021916908360048111156200002d576200002c6200039f565b5b02179055503480156200003f57600080fd5b506040516200631238038062006312833981810160405281019062000065919062000438565b60016000819055506000600160006101000a81548160ff021916908315150217905550620000a86200009c620002d460201b60201c565b620002dc60201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060a001604052806050815260200160018152602001600143620001119190620004a3565b8152602001600081526020016050815250600360008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506014600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ef91906200051c565b600a620001fd9190620006a2565b62000209919062000722565b600881905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a391906200051c565b600a620002b19190620006a2565b6001620002bf91906200075a565b6009819055506000600b8190555050620007a5565b600033905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040082620003d3565b9050919050565b6200041281620003f3565b81146200041e57600080fd5b50565b600081519050620004328162000407565b92915050565b600060208284031215620004515762000450620003ce565b5b6000620004618482850162000421565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004b0826200046a565b9150620004bd836200046a565b9250828201905080821115620004d857620004d762000474565b5b92915050565b600060ff82169050919050565b620004f681620004de565b81146200050257600080fd5b50565b6000815190506200051681620004eb565b92915050565b600060208284031215620005355762000534620003ce565b5b6000620005458482850162000505565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115620005ad5780860481111562000585576200058462000474565b5b6001851615620005955780820291505b8081029050620005a5856200054e565b945062000565565b94509492505050565b600082620005c857600190506200069b565b81620005d857600090506200069b565b8160018114620005f15760028114620005fc5762000632565b60019150506200069b565b60ff84111562000611576200061062000474565b5b8360020a9150848211156200062b576200062a62000474565b5b506200069b565b5060208310610133831016604e8410600b84101617156200066c5782820a90508381111562000666576200066562000474565b5b6200069b565b6200067b84848460016200055b565b9250905081840481111562000695576200069462000474565b5b81810290505b9392505050565b6000620006af826200046a565b9150620006bc83620004de565b9250620006eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620005b6565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006200072f826200046a565b91506200073c836200046a565b9250826200074f576200074e620006f3565b5b828204905092915050565b600062000767826200046a565b915062000774836200046a565b925082820262000784816200046a565b915082820484148315176200079e576200079d62000474565b5b5092915050565b615b5d80620007b56000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea2646970667358221220027cb3a268941c42576d32dd6d99cc264ae7a5e0cd262b8785c1d99ed51ca01164736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea2646970667358221220027cb3a268941c42576d32dd6d99cc264ae7a5e0cd262b8785c1d99ed51ca01164736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"EpochLengthSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"EpochTimeoutSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"KickPenaltyPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"MinimumStakeSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"ReadyForNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"ResolverContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"StakingTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"StateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"TokenRewardPerTokenPerEpochSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBurned","type":"uint256"}],"name":"ValidatorKickedFromNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reporter","type":"address"},{"indexed":true,"internalType":"address","name":"validatorStakerAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"reason","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"VotedToKickValidatorInNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"}],"name":"adminKickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"amountToBurn","type":"uint256"}],"name":"adminSlashValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"advanceEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"epochLength","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"retries","type":"uint256"},{"internalType":"uint256","name":"timeout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValidatorsInCurrentEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorsInNextEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochNumber","type":"uint256"},{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"address","name":"voterStakerAddress","type":"address"}],"name":"getVotingStatusToKickValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isActiveValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReadyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickPenaltyPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"reason","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"kickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nodeAddressToStakerAddress","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":"pauseEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"requestToJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestToLeave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolverContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"setEpochLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"setEpochState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"setEpochTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"setIpPortNodeAddressAndCommunicationPubKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"setKickPenaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"setResolverContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"setStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"setTokenRewardPerTokenPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"shouldKickValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signalReadyForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"stakeAndJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract LITToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Staking.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenRewardPerTokenPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorCountForConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsInNextEpochAreLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votesToKickValidatorsInNextEpoch","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/AccessControlConditions.json b/deployments/localchain_31337/AccessControlConditions.json deleted file mode 100644 index 8743a1d..0000000 --- a/deployments/localchain_31337/AccessControlConditions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/AccessControlConditions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract AccessControlConditions is Ownable, ReentrancyGuard {\\n /* ========== STRUCTS ========== */\\n struct StoredCondition {\\n uint256 value;\\n uint256 securityHash;\\n uint256 chainId;\\n bool permanent;\\n address creator;\\n }\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(uint256 => StoredCondition) public storedConditions;\\n address public signer;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n signer = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function getCondition(uint256 key)\\n external\\n view\\n returns (StoredCondition memory)\\n {\\n return storedConditions[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent\\n ) external nonReentrant {\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n msg.sender\\n );\\n }\\n\\n function storeConditionWithSigner(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) external nonReentrant {\\n require(\\n msg.sender == signer,\\n \\\"Only signer can call storeConditionsWithSigner.\\\"\\n );\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n }\\n\\n function setSigner(address newSigner) public onlyOwner {\\n signer = newSigner;\\n }\\n\\n /* ========== PRIVATE FUNCTIONS ========== */\\n\\n function _storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) private {\\n require(key != 0, \\\"Key must not be zero\\\");\\n if (storedConditions[key].creator != address(0)) {\\n // this is an update\\n require(\\n storedConditions[key].creator == creatorAddress,\\n \\\"Only the condition creator can update it\\\"\\n );\\n require(\\n storedConditions[key].permanent == false,\\n \\\"This condition was stored with the Permanent flag and cannot be updated\\\"\\n );\\n require(msg.sender != signer, \\\"Signer cannot update conditions\\\");\\n }\\n storedConditions[key] = StoredCondition(\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n\\n emit ConditionStored(key, value, chainId, permanent, creatorAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ConditionStored(\\n uint256 indexed key,\\n uint256 value,\\n uint256 chainId,\\n bool permanent,\\n address creator\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x0B306BF915C4d645ff596e518fAf3F9669b97016","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261007a60201b60201c565b61008260201b60201c565b6001808190555033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610146565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61128b806101556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"permanent","type":"bool"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"ConditionStored","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":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getCondition","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"internalType":"struct AccessControlConditions.StoredCondition","name":"","type":"tuple"}],"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":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"}],"name":"storeCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"storeConditionWithSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"storedConditions","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/Allowlist.json b/deployments/localchain_31337/Allowlist.json deleted file mode 100644 index cc27039..0000000 --- a/deployments/localchain_31337/Allowlist.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Allowlist.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Allowlist is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(bytes32 => bool) public allowedItems;\\n EnumerableSet.AddressSet admins;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n admins.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function isAllowed(bytes32 key) external view returns (bool) {\\n return allowedItems[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function setAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = true;\\n emit ItemAllowed(key);\\n }\\n\\n function setNotAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = false;\\n emit ItemNotAllowed(key);\\n }\\n\\n function addAdmin(address newAdmin) public onlyOwner {\\n admins.add(newAdmin);\\n emit AdminAdded(newAdmin);\\n }\\n\\n function removeAdmin(address newAdmin) public onlyOwner {\\n admins.remove(newAdmin);\\n emit AdminRemoved(newAdmin);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ItemAllowed(bytes32 indexed key);\\n event ItemNotAllowed(bytes32 indexed key);\\n event AdminAdded(address indexed newAdmin);\\n event AdminRemoved(address indexed newAdmin);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261005260201b60201c565b61005a60201b60201c565b6001808190555061004c33600361011e60201b6104da1790919060201c565b506101ed565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061014c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61015460201b60201c565b905092915050565b600061016683836101ca60201b60201c565b6101bf5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506101c4565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b610c2a806101fc6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemNotAllowed","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":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"allowedItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/Multisender.json b/deployments/localchain_31337/Multisender.json deleted file mode 100644 index e7f6dac..0000000 --- a/deployments/localchain_31337/Multisender.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Multisender.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// This contract does one thing, simply. it allows you to send eth or tokens to multiple recipients. Useful for setting up a testnet and funding all the validators and stakers.\\n\\ncontract Multisender is Ownable {\\n function sendEth(address[] calldata _recipients) public payable {\\n uint256 val = msg.value / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n payable(_recipients[i]).transfer(val);\\n }\\n }\\n\\n function sendTokens(address[] calldata _recipients, address tokenContract)\\n public\\n {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n uint256 val = bal / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n tkn.transfer(_recipients[i], val);\\n }\\n }\\n\\n function withdraw() public onlyOwner {\\n payable(msg.sender).transfer(address(this).balance);\\n }\\n\\n function withdrawTokens(address tokenContract) public onlyOwner {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n tkn.transfer(msg.sender, bal);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610bf98061010d6000396000f3fe6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","abi":[{"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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"sendEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"address","name":"tokenContract","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/PKPNFTMetadata.json b/deployments/localchain_31337/PKPNFTMetadata.json deleted file mode 100644 index 479af29..0000000 --- a/deployments/localchain_31337/PKPNFTMetadata.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x09635F643e140090A9A8Dcd712eD6285858ceBef","bytecode":"0x608060405234801561001057600080fd5b506117de806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"buffer","type":"bytes"}],"name":"bytesToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"address","name":"ethAddress","type":"address"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/PKPPermissions.json b/deployments/localchain_31337/PKPPermissions.json deleted file mode 100644 index 9587c6e..0000000 --- a/deployments/localchain_31337/PKPPermissions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x67d269191c92Caf3cD7723F116c85e6E9bf55933","bytecode":"0x60806040523480156200001157600080fd5b5060405162005087380380620050878339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b614e7080620002176000396000f3fe608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea26469706673582212204f8a2910f560efadc643fb8c043d4f86c1738e61127cd1d5bf70d40aa52307f764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea26469706673582212204f8a2910f560efadc643fb8c043d4f86c1738e61127cd1d5bf70d40aa52307f764736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"userPubkey","type":"bytes"}],"name":"PermittedAuthMethodAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"}],"name":"PermittedAuthMethodRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"group","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootHashUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod","name":"authMethod","type":"tuple"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"addPermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"authMethods","outputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getAuthMethodId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedActions","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"maxScopeId","type":"uint256"}],"name":"getPermittedAuthMethodScopes","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAuthMethods","outputs":[{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getTokenIdsForAuthMethod","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getUserPubkeyForAuthMethod","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"isPermittedAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isPermittedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"isPermittedAuthMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"isPermittedAuthMethodScopePresent","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"removePermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"removePermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"removePermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"removePermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verifyState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool[]","name":"proofFlags","type":"bool[]"},{"internalType":"bytes32[]","name":"leaves","type":"bytes32[]"}],"name":"verifyStates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/RateLimitNFT.json b/deployments/localchain_31337/RateLimitNFT.json deleted file mode 100644 index 1e03aaa..0000000 --- a/deployments/localchain_31337/RateLimitNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/RateLimitNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Rate Limit NFT\\n///\\n/// @dev This is the contract for the Rate Limit NFTs\\n/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit\\n/// And how it works, is that you can buy X requestsPerKilosecond over a period of time\\n/// 1 requestsPerKilosecond = 0.001 requests per second and\\n/// 1000 requestsPerKilosecond = 1 request per second\\ncontract RateLimitNFT is\\n ERC721(\\\"Rate Limit Increases on Lit Protocol\\\", \\\"RLI\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using Strings for uint256;\\n /* ========== STATE VARIABLES ========== */\\n\\n address public freeMintSigner;\\n uint256 public additionalRequestsPerKilosecondCost;\\n uint256 public tokenIdCounter;\\n uint256 public defaultRateLimitWindowSeconds = 60 * 60; // 60 mins\\n uint256 public RLIHolderRateLimitWindowSeconds = 5 * 60; // 5 mins\\n uint256 public freeRequestsPerRateLimitWindow = 10;\\n\\n mapping(uint256 => RateLimit) public capacity;\\n mapping(bytes32 => bool) public redeemedFreeMints;\\n\\n struct RateLimit {\\n uint256 requestsPerKilosecond;\\n uint256 expiresAt;\\n }\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n // make sure the msgHash matches the tokenId\\n // if these don't match, the user could use any old signature\\n // to mint any number of PKPs\\n // and this would be vulnerable to replay attacks\\n // FIXME this needs the whole \\\"ethereum signed message: \\\\27\\\" thingy prepended to actually work\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // make sure it hasn't already been redeemed\\n require(\\n !redeemedFreeMints[msgHash],\\n \\\"This freeMint has already been redeemed. How embarassing.\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function calculateCost(\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n require(\\n requestsPerKilosecond > 0,\\n \\\"The requestsPerKilosecond must be greater than 0\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n\\n // calculate the cost\\n uint256 cost = (requestsPerKilosecond *\\n durationInSeconds *\\n additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return cost;\\n }\\n\\n function calculateRequestsPerKilosecond(\\n uint256 payingAmount,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n // console.log(\\\"durationInSeconds: \\\");\\n // console.log(durationInSeconds);\\n\\n // calculate the cost\\n uint256 requestsPerKilosecond = payingAmount /\\n ((durationInSeconds * additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return requestsPerKilosecond;\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit Protocol Rate Limit Increase\\\", \\\"description\\\": \\\"This NFT entitles the holder to a rate limit increase on the Lit Protocol Network\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"display_type\\\": \\\"date\\\", \\\"trait_type\\\": \\\"Expiration Date\\\", \\\"value\\\": ',\\n capacity[tokenId].expiresAt.toString(),\\n '}, {\\\"display_type\\\": \\\"number\\\", \\\"trait_type\\\": \\\"Millirequests Per Second\\\", \\\"value\\\": ',\\n capacity[tokenId].requestsPerKilosecond.toString(),\\n \\\"}]}\\\"\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n\\n function isExpired(uint256 tokenId) public view returns (bool) {\\n return capacity[tokenId].expiresAt <= block.timestamp;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function.\\n function mint(uint256 expiresAt) public payable returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n uint256 requestsPerKilosecond = calculateRequestsPerKilosecond(\\n msg.value,\\n expiresAt\\n );\\n\\n // sanity check\\n uint256 cost = calculateCost(requestsPerKilosecond, expiresAt);\\n\\n require(\\n msg.value > 0 && msg.value >= cost,\\n \\\"You must send the cost of this rate limit increase. To check the cost, use the calculateCost function.\\\"\\n );\\n require(cost > 0, \\\"The cost must be greater than 0\\\");\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function freeMint(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(expiresAt, requestsPerKilosecond, msgHash, v, r, s);\\n redeemedFreeMints[msgHash] = true;\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n uint256 tokenId,\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) internal {\\n _safeMint(msg.sender, tokenId);\\n capacity[tokenId] = RateLimit(requestsPerKilosecond, expiresAt);\\n }\\n\\n function setAdditionalRequestsPerKilosecondCost(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n ) public onlyOwner {\\n additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost;\\n emit AdditionalRequestsPerKilosecondCostSet(\\n newAdditionalRequestsPerKilosecondCost\\n );\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n function setRateLimitWindowSeconds(\\n uint256 newRateLimitWindowSeconds\\n ) public onlyOwner {\\n defaultRateLimitWindowSeconds = newRateLimitWindowSeconds;\\n emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds);\\n }\\n\\n function setRLIHolderRateLimitWindowSeconds(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n ) public onlyOwner {\\n RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds;\\n emit RLIHolderRateLimitWindowSecondsSet(\\n newRLIHolderRateLimitWindowSeconds\\n );\\n }\\n\\n function setFreeRequestsPerRateLimitWindow(\\n uint256 newFreeRequestsPerRateLimitWindow\\n ) public onlyOwner {\\n freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow;\\n emit FreeRequestsPerRateLimitWindowSet(\\n newFreeRequestsPerRateLimitWindow\\n );\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event AdditionalRequestsPerKilosecondCostSet(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n );\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds);\\n event RLIHolderRateLimitWindowSecondsSet(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n );\\n event FreeRequestsPerRateLimitWindowSet(\\n uint256 newFreeRequestsPerRateLimitWindow\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xc6e7DF5E7b4f2A278906862b61205850344D4e7d","bytecode":"0x6080604052610e10600f5561012c601055600a6011553480156200002257600080fd5b50604051806060016040528060248152602001620055f8602491396040518060400160405280600381526020017f524c490000000000000000000000000000000000000000000000000000000000815250816000908162000084919062000419565b50806001908162000096919062000419565b505050620000b9620000ad620000d160201b60201c565b620000d960201b60201c565b6001600b81905550620f4240600d8190555062000500565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200022157607f821691505b602082108103620002375762000236620001d9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000262565b620002ad868362000262565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002fa620002f4620002ee84620002c5565b620002cf565b620002c5565b9050919050565b6000819050919050565b6200031683620002d9565b6200032e620003258262000301565b8484546200026f565b825550505050565b600090565b6200034562000336565b620003528184846200030b565b505050565b5b818110156200037a576200036e6000826200033b565b60018101905062000358565b5050565b601f821115620003c95762000393816200023d565b6200039e8462000252565b81016020851015620003ae578190505b620003c6620003bd8562000252565b83018262000357565b50505b505050565b600082821c905092915050565b6000620003ee60001984600802620003ce565b1980831691505092915050565b6000620004098383620003db565b9150826002028217905092915050565b62000424826200019f565b67ffffffffffffffff81111562000440576200043f620001aa565b5b6200044c825462000208565b620004598282856200037e565b600060209050601f8311600181146200049157600084156200047c578287015190505b620004888582620003fb565b865550620004f8565b601f198416620004a1866200023d565b60005b82811015620004cb57848901518255600182019150602085019450602081019050620004a4565b86831015620004eb5784890151620004e7601f891682620003db565b8355505b6001600288020188555050505b505050505050565b6150e880620005106000396000f3fe6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c6343000811003352617465204c696d697420496e63726561736573206f6e204c69742050726f746f636f6c","deployedBytecode":"0x6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"AdditionalRequestsPerKilosecondCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"FreeRequestsPerRateLimitWindowSet","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":false,"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"RLIHolderRateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"RateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"RLIHolderRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalRequestsPerKilosecondCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payingAmount","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateRequestsPerKilosecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capacity","outputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeRequestsPerRateLimitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"isExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"redeemedFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"setAdditionalRequestsPerKilosecondCost","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"setFreeRequestsPerRateLimitWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"setRLIHolderRateLimitWindowSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"setRateLimitWindowSeconds","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/SoloNetPKP.json b/deployments/localchain_31337/SoloNetPKP.json deleted file mode 100644 index 703f033..0000000 --- a/deployments/localchain_31337/SoloNetPKP.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x3Aa5ebB10DC797CAC828524e59A333d0A371443c","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000559565b508060019081620000a1919062000559565b505050620000c4620000b86200013c60201b60201c565b6200014460201b60201c565b6001600b81905550655af3107a4000600e8190555033600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001353360116200020a60201b6200240d1790919060201c565b5062000640565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006200023a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200024260201b60201c565b905092915050565b6000620002568383620002bc60201b60201c565b620002b1578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050620002b6565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200036157607f821691505b60208210810362000377576200037662000319565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003a2565b620003ed8683620003a2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200043a620004346200042e8462000405565b6200040f565b62000405565b9050919050565b6000819050919050565b620004568362000419565b6200046e620004658262000441565b848454620003af565b825550505050565b600090565b6200048562000476565b620004928184846200044b565b505050565b5b81811015620004ba57620004ae6000826200047b565b60018101905062000498565b5050565b601f8211156200050957620004d3816200037d565b620004de8462000392565b81016020851015620004ee578190505b62000506620004fd8562000392565b83018262000497565b50505b505050565b600082821c905092915050565b60006200052e600019846008026200050e565b1980831691505092915050565b60006200054983836200051b565b9150826002028217905092915050565b6200056482620002df565b67ffffffffffffffff81111562000580576200057f620002ea565b5b6200058c825462000348565b62000599828285620004be565b600060209050601f831160018114620005d15760008415620005bc578287015190505b620005c885826200053b565b86555062000638565b601f198416620005e1866200037d565b60005b828110156200060b57848901518255600182019150602085019450602081019050620005e4565b868310156200062b578489015162000627601f8916826200051b565b8355505b6001600288020188555050505b505050505050565b61598b80620006506000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122080cad9d7cc14690992b06395c8008178c79f26b0a2a260deb1a280e2b6d649e564736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122080cad9d7cc14690992b06395c8008178c79f26b0a2a260deb1a280e2b6d649e564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterPermitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRevoked","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingAddress","type":"address"}],"name":"StakingAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"_getTokenIdToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"addPermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"removePermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/SoloNetPKPHelper.json b/deployments/localchain_31337/SoloNetPKPHelper.json deleted file mode 100644 index d85a597..0000000 --- a/deployments/localchain_31337/SoloNetPKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { SoloNetPKP } from \\\"./SoloNetPKP.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/// @title PKP Helper Contract\\n///\\n/// @dev This is the contract that helps minting PKPs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n SoloNetPKP public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = SoloNetPKP(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintAndAddAuthMethods(\\n bytes memory pubkey,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintAndAddAuthMethodsWithTypes(\\n pubkey,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintAndAddAuthMethodsWithTypes(\\n bytes memory pubkey,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpNFT.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = SoloNetPKP(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1; // 1 wei aka 0.000000000000000001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(\\n uint256 keyType\\n ) public view returns (uint256) {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(\\n uint256 keyType,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(\\n uint256 tokenId,\\n bytes memory ipfsCID\\n ) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB","bytecode":"0x60806040523480156200001157600080fd5b506040516200254d3803806200254d833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b6122df806200026e6000396000f3fe6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220fe76437deb86295c7e3dcef45d4697442e812480a8078c5ca0787a3b750cf99464736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220fe76437deb86295c7e3dcef45d4697442e812480a8078c5ca0787a3b750cf99464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract SoloNetPKP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/Staking.json b/deployments/localchain_31337/Staking.json deleted file mode 100644 index 514fa0d..0000000 --- a/deployments/localchain_31337/Staking.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n ERC20Burnable public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = ERC20Burnable(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.transferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.transfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.transfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = ERC20Burnable(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82","bytecode":"0x60806040526000600160156101000a81548160ff021916908360048111156200002d576200002c6200039f565b5b02179055503480156200003f57600080fd5b5060405162005e0438038062005e04833981810160405281019062000065919062000438565b60016000819055506000600160006101000a81548160ff021916908315150217905550620000a86200009c620002d460201b60201c565b620002dc60201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060a001604052806050815260200160018152602001600143620001119190620004a3565b8152602001600081526020016050815250600360008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506014600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ef91906200051c565b600a620001fd9190620006a2565b62000209919062000722565b600881905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a391906200051c565b600a620002b19190620006a2565b6001620002bf91906200075a565b6009819055506000600b8190555050620007a5565b600033905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040082620003d3565b9050919050565b6200041281620003f3565b81146200041e57600080fd5b50565b600081519050620004328162000407565b92915050565b600060208284031215620004515762000450620003ce565b5b6000620004618482850162000421565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004b0826200046a565b9150620004bd836200046a565b9250828201905080821115620004d857620004d762000474565b5b92915050565b600060ff82169050919050565b620004f681620004de565b81146200050257600080fd5b50565b6000815190506200051681620004eb565b92915050565b600060208284031215620005355762000534620003ce565b5b6000620005458482850162000505565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115620005ad5780860481111562000585576200058462000474565b5b6001851615620005955780820291505b8081029050620005a5856200054e565b945062000565565b94509492505050565b600082620005c857600190506200069b565b81620005d857600090506200069b565b8160018114620005f15760028114620005fc5762000632565b60019150506200069b565b60ff84111562000611576200061062000474565b5b8360020a9150848211156200062b576200062a62000474565b5b506200069b565b5060208310610133831016604e8410600b84101617156200066c5782820a90508381111562000666576200066562000474565b5b6200069b565b6200067b84848460016200055b565b9250905081840481111562000695576200069462000474565b5b81810290505b9392505050565b6000620006af826200046a565b9150620006bc83620004de565b9250620006eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620005b6565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006200072f826200046a565b91506200073c836200046a565b9250826200074f576200074e620006f3565b5b828204905092915050565b600062000767826200046a565b915062000774836200046a565b925082820262000784816200046a565b915082820484148315176200079e576200079d62000474565b5b5092915050565b61564f80620007b56000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613c4d565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613cd0565b610a75565b6040516103609190613c4d565b60405180910390f35b610383600480360381019061037e9190613cd0565b610ac1565b005b61039f600480360381019061039a9190613d29565b610b44565b005b6103bb60048036038101906103b69190613d29565b610b90565b005b6103d760048036038101906103d29190613d29565b610bd9565b005b6103f360048036038101906103ee9190613dda565b610eea565b005b6103fd61143f565b005b610407611888565b005b610423600480360381019061041e9190613e8c565b611a68565b005b61043f600480360381019061043a9190613cd0565b611ad4565b60405161044c9190613ed4565b60405180910390f35b61046f600480360381019061046a9190613d29565b611af1565b005b61048b60048036038101906104869190613eef565b611b3a565b6040516104989190613c4d565b60405180910390f35b6104bb60048036038101906104b69190613dda565b611b65565b005b6104d760048036038101906104d29190613cd0565b611db7565b6040516104e49190613f3e565b60405180910390f35b61050760048036038101906105029190613cd0565b611dea565b6040516105149190613ed4565b60405180910390f35b61053760048036038101906105329190613d29565b611e0a565b005b610541611e56565b60405161054e9190613ed4565b60405180910390f35b610571600480360381019061056c9190613cd0565b611e6d565b60405161057e9190613c4d565b60405180910390f35b6105a1600480360381019061059c9190613f59565b611eb9565b6040516105af929190613fac565b60405180910390f35b6105c0611f71565b005b6105ca611f85565b6040516105d79190614034565b60405180910390f35b6105fa60048036038101906105f59190613cd0565b611fab565b005b610604612084565b6040516106119190613c4d565b60405180910390f35b610634600480360381019061062f9190613cd0565b61208a565b6040516106419190613ed4565b60405180910390f35b61065261210b565b60405161065f919061410d565b60405180910390f35b610682600480360381019061067d9190614194565b6121f9565b005b61069e60048036038101906106999190614208565b6127eb565b005b6106a8612999565b6040516106b59190613ed4565b60405180910390f35b6106c66129d7565b6040516106d39190613f3e565b60405180910390f35b6106e46129ff565b6040516106f5959493929190614248565b60405180910390f35b61071860048036038101906107139190613cd0565b612a23565b005b610722612aa6565b60405161072f9190613ed4565b60405180910390f35b610752600480360381019061074d9190613d29565b612ae3565b005b61075c612ce1565b005b610766612e9b565b005b610770612f08565b60405161077d9190613f3e565b60405180910390f35b61078e612f2e565b60405161079b9190613c4d565b60405180910390f35b6107be60048036038101906107b9919061429b565b612f34565b005b6107c8612f5c565b005b6107d26131f2565b005b6107dc6133e6565b6040516107e991906143b4565b60405180910390f35b6107fa6133f9565b604051610807919061410d565b60405180910390f35b6108186134e7565b6040516108259190613c4d565b60405180910390f35b61084860048036038101906108439190613d29565b61352b565b005b610852613574565b005b61085c6135c9565b6040516108699190613c4d565b60405180910390f35b61087a6135cf565b6040516108879190613ed4565b60405180910390f35b6108aa60048036038101906108a59190613cd0565b61369a565b005b6108b461371d565b6040516108c19190613ed4565b60405180910390f35b6108e460048036038101906108df9190613cd0565b61375b565b6040516108f89897969594939291906143ed565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610946906144ee565b60405180910390fd5b600060048111156109635761096261433d565b5b600160159054906101000a900460ff1660048111156109855761098461433d565b5b14806109c45750600360048111156109a05761099f61433d565b5b600160159054906101000a900460ff1660048111156109c2576109c161433d565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614580565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a2761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b91906143b4565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac96137ff565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b399190613f3e565b60405180910390a150565b610b4c6137ff565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613c4d565b60405180910390a150565b610b986137ff565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613c4d565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c15906145ec565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6090614658565b60405180910390fd5b60001515610c8133600c61387d90919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90614736565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f906147a2565b60405180910390fd5b80600a54610d5691906147f1565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa91906147f1565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610e4d929190614825565b6020604051808303816000875af1158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e90919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610ed79190613c4d565b60405180910390a2600160008190555050565b600260005403610f2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f26906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610fc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fba90614919565b60405180910390fd5b60006004811115610fd757610fd661433d565b5b600160159054906101000a900460ff166004811115610ff957610ff861433d565b5b14806110385750600360048111156110145761101361433d565b5b600160159054906101000a900460ff1660048111156110365761103561433d565b5b145b8061107557506004808111156110515761105061433d565b5b600160159054906101000a900460ff1660048111156110735761107261433d565b5b145b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ab906149ab565b60405180910390fd5b600015156110cc33601061387d90919063ffffffff16565b15151461110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590614a3d565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea33600e6138ad90919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147e906144ee565b60405180910390fd5b6002600481111561149b5761149a61433d565b5b600160159054906101000a900460ff1660048111156114bd576114bc61433d565b5b146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f490614acf565b60405180910390fd5b600115156115096135cf565b15151461154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154290614b61565b60405180910390fd5b6000611557600c6138dd565b905060005b818110156116df57600061157a82600c6138f290919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190614bba565b600a6116199190614d1a565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116699190614d65565b6116739190614dd6565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116c49190614e07565b925050819055505080806116d790614e3b565b91505061155c565b505b60006116ed600c6138dd565b11156117215761171b61170b6000600c6138f290919063ffffffff16565b600c61390c90919063ffffffff16565b506116e1565b61172b600e6138dd565b905060005b818110156117de5761175f61174f82600e6138f290919063ffffffff16565b600c6138ad90919063ffffffff16565b5060006014600061177a84600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806117d690614e3b565b915050611730565b50600360010160008154809291906117f590614e3b565b91905055506003600001544361180b9190614e07565b6003600201819055506000600160156101000a81548160ff0219169083600481111561183a5761183961433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff1660405161187d91906143b4565b60405180910390a150565b6002600054036118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000811115611a5d576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016119ca929190614825565b6020604051808303816000875af11580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611a549190613c4d565b60405180910390a25b506001600081905550565b611a706137ff565b80600160156101000a81548160ff02191690836004811115611a9557611a9461433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611ac991906143b4565b60405180910390a150565b6000611aea82600c61387d90919063ffffffff16565b9050919050565b611af96137ff565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611b2f9190613c4d565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611e126137ff565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611e4b9190613c4d565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611f796137ff565b611f83600061393c565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe7906145ec565b60405180910390fd5b60026000819055506120006137ff565b61201481600e61390c90919063ffffffff16565b506120298160106138ad90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e9760006040516120719190614ebe565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120ec6134e7565b816000015410612100576001915050612106565b60009150505b919050565b60606000612119600c6138dd565b67ffffffffffffffff81111561213257612131614ed9565b5b6040519080825280602002602001820160405280156121605781602001602082028036833780820191505090505b509050600061216f600c6138dd565b905060005b818110156121f05761219081600c6138f290919063ffffffff16565b8382815181106121a3576121a2614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806121e890614e3b565b915050612174565b50819250505090565b60026000540361223e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612235906145ec565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fa9565b60405180910390fd5b61232d81600e61387d90919063ffffffff16565b61236c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236390615061565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c906150f3565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008154809291906124be90614e3b565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061258585600e61387d90919063ffffffff16565b801561259657506125958561208a565b5b15612774576125af85600e61390c90919063ffffffff16565b506125c48560106138ad90919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546126199190614d65565b6126239190614dd6565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461267791906147f1565b9250508190555080600a600082825461269091906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016126f29190613c4d565b600060405180830381600087803b15801561270c57600080fd5b505af1158015612720573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e978260405161276a9190613c4d565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa86866040516127d4929190615171565b60405180910390a450600160008190555050505050565b600260005403612830576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612827906145ec565b60405180910390fd5b60026000819055506128406137ff565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461289291906147f1565b9250508190555080600a60008282546128ab91906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161290d9190613c4d565b600060405180830381600087803b15801561292757600080fd5b505af115801561293b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516129859190613c4d565b60405180910390a260016000819055505050565b6000600160048111156129af576129ae61433d565b5b600160159054906101000a900460ff1660048111156129d1576129d061433d565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612a2b6137ff565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a607581604051612a9b9190613f3e565b60405180910390a150565b6000806004811115612abb57612aba61433d565b5b600160159054906101000a900460ff166004811115612add57612adc61433d565b5b14905090565b600260005403612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f906145ec565b60405180910390fd5b600260008190555060008111612b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6a906151e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401612bd293929190615201565b6020604051808303816000875af1158015612bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c15919061487a565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612c689190614e07565b9250508190555080600a6000828254612c819190614e07565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612cce9190613c4d565b60405180910390a2600160008190555050565b600260005403612d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1d906145ec565b60405180910390fd5b600260008190555060006004811115612d4257612d4161433d565b5b600160159054906101000a900460ff166004811115612d6457612d6361433d565b5b1480612da3575060036004811115612d7f57612d7e61433d565b5b600160159054906101000a900460ff166004811115612da157612da061433d565b5b145b80612de05750600480811115612dbc57612dbb61433d565b5b600160159054906101000a900460ff166004811115612dde57612ddd61433d565b5b145b612e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e16906152aa565b60405180910390fd5b612e3333600e61387d90919063ffffffff16565b15612e4e57612e4c33600e61390c90919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612ea36137ff565b6004600160156101000a81548160ff02191690836004811115612ec957612ec861433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612efe91906143b4565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612f3c6139ff565b612f4587612ae3565b612f53868686868686610eea565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612fd457612fd361433d565b5b600160159054906101000a900460ff166004811115612ff657612ff561433d565b5b14806130355750600260048111156130115761301061433d565b5b600160159054906101000a900460ff1660048111156130335761303261433d565b5b145b613074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306b9061533c565b60405180910390fd5b6001600360010154146130d55761309581600e61387d90919063ffffffff16565b6130d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cb906153ce565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a26131786135cf565b156131ef576002600160156101000a81548160ff021916908360048111156131a3576131a261433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516131e691906143b4565b60405180910390a15b50565b6003600401546003600201546132089190614e07565b43101561324a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613241906144ee565b60405180910390fd5b6001600481111561325e5761325d61433d565b5b600160159054906101000a900460ff1660048111156132805761327f61433d565b5b146132c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132b790615460565b60405180910390fd5b60006132cc600e6138dd565b905060005b81811015613357576000601460006132f384600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061334f90614e3b565b9150506132d1565b5060038001600081548092919061336d90614e3b565b91905055506003600160156101000a81548160ff021916908360048111156133985761339761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516133db91906143b4565b60405180910390a150565b600160159054906101000a900460ff1681565b60606000613407600e6138dd565b67ffffffffffffffff8111156134205761341f614ed9565b5b60405190808252806020026020018201604052801561344e5781602001602082028036833780820191505090505b509050600061345d600e6138dd565b905060005b818110156134de5761347e81600e6138f290919063ffffffff16565b83828151811061349157613490614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806134d690614e3b565b915050613462565b50819250505090565b600060026134f5600c6138dd565b116135035760019050613528565b60036002613511600c6138dd565b61351b9190614d65565b6135259190614dd6565b90505b90565b6135336137ff565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a5816040516135699190613c4d565b60405180910390a150565b6135bf601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6135c7611888565b565b60095481565b6000806000905060006135e2600e6138dd565b905060005b81811015613676576014600061360783600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561366357828061365f90614e3b565b9350505b808061366e90614e3b565b9150506135e7565b5061367f6134e7565b821061369057600192505050613697565b6000925050505b90565b6136a26137ff565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613711576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613708906154f2565b60405180910390fd5b61371a8161393c565b50565b6000600360048111156137335761373261433d565b5b600160159054906101000a900460ff1660048111156137555761375461433d565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b613807613a49565b73ffffffffffffffffffffffffffffffffffffffff166138256129d7565b73ffffffffffffffffffffffffffffffffffffffff161461387b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138729061555e565b60405180910390fd5b565b60006138a5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a51565b905092915050565b60006138d5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a74565b905092915050565b60006138eb82600001613ae4565b9050919050565b60006139018360000183613af5565b60001c905092915050565b6000613934836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b20565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a07611e56565b15613a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a3e906155ca565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613a808383613a51565b613ad9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613ade565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613b0d57613b0c614f08565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613c28576000600182613b5291906147f1565b9050600060018660000180549050613b6a91906147f1565b9050818114613bd9576000866000018281548110613b8b57613b8a614f08565b5b9060005260206000200154905080876000018481548110613baf57613bae614f08565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613bed57613bec6155ea565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613c2e565b60009150505b92915050565b6000819050919050565b613c4781613c34565b82525050565b6000602082019050613c626000830184613c3e565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c9d82613c72565b9050919050565b613cad81613c92565b8114613cb857600080fd5b50565b600081359050613cca81613ca4565b92915050565b600060208284031215613ce657613ce5613c68565b5b6000613cf484828501613cbb565b91505092915050565b613d0681613c34565b8114613d1157600080fd5b50565b600081359050613d2381613cfd565b92915050565b600060208284031215613d3f57613d3e613c68565b5b6000613d4d84828501613d14565b91505092915050565b600063ffffffff82169050919050565b613d6f81613d56565b8114613d7a57600080fd5b50565b600081359050613d8c81613d66565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613db781613d92565b8114613dc257600080fd5b50565b600081359050613dd481613dae565b92915050565b60008060008060008060c08789031215613df757613df6613c68565b5b6000613e0589828a01613d7d565b9650506020613e1689828a01613dc5565b9550506040613e2789828a01613d7d565b9450506060613e3889828a01613cbb565b9350506080613e4989828a01613d14565b92505060a0613e5a89828a01613d14565b9150509295509295509295565b60058110613e7457600080fd5b50565b600081359050613e8681613e67565b92915050565b600060208284031215613ea257613ea1613c68565b5b6000613eb084828501613e77565b91505092915050565b60008115159050919050565b613ece81613eb9565b82525050565b6000602082019050613ee96000830184613ec5565b92915050565b60008060408385031215613f0657613f05613c68565b5b6000613f1485828601613d14565b9250506020613f2585828601613cbb565b9150509250929050565b613f3881613c92565b82525050565b6000602082019050613f536000830184613f2f565b92915050565b600080600060608486031215613f7257613f71613c68565b5b6000613f8086828701613d14565b9350506020613f9186828701613cbb565b9250506040613fa286828701613cbb565b9150509250925092565b6000604082019050613fc16000830185613c3e565b613fce6020830184613ec5565b9392505050565b6000819050919050565b6000613ffa613ff5613ff084613c72565b613fd5565b613c72565b9050919050565b600061400c82613fdf565b9050919050565b600061401e82614001565b9050919050565b61402e81614013565b82525050565b60006020820190506140496000830184614025565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61408481613c92565b82525050565b6000614096838361407b565b60208301905092915050565b6000602082019050919050565b60006140ba8261404f565b6140c4818561405a565b93506140cf8361406b565b8060005b838110156141005781516140e7888261408a565b97506140f2836140a2565b9250506001810190506140d3565b5085935050505092915050565b6000602082019050818103600083015261412781846140af565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141545761415361412f565b5b8235905067ffffffffffffffff81111561417157614170614134565b5b60208301915083600182028301111561418d5761418c614139565b5b9250929050565b600080600080606085870312156141ae576141ad613c68565b5b60006141bc87828801613cbb565b94505060206141cd87828801613d14565b935050604085013567ffffffffffffffff8111156141ee576141ed613c6d565b5b6141fa8782880161413e565b925092505092959194509250565b6000806040838503121561421f5761421e613c68565b5b600061422d85828601613cbb565b925050602061423e85828601613d14565b9150509250929050565b600060a08201905061425d6000830188613c3e565b61426a6020830187613c3e565b6142776040830186613c3e565b6142846060830185613c3e565b6142916080830184613c3e565b9695505050505050565b600080600080600080600060e0888a0312156142ba576142b9613c68565b5b60006142c88a828b01613d14565b97505060206142d98a828b01613d7d565b96505060406142ea8a828b01613dc5565b95505060606142fb8a828b01613d7d565b945050608061430c8a828b01613cbb565b93505060a061431d8a828b01613d14565b92505060c061432e8a828b01613d14565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061437d5761437c61433d565b5b50565b600081905061438e8261436c565b919050565b600061439e82614380565b9050919050565b6143ae81614393565b82525050565b60006020820190506143c960008301846143a5565b92915050565b6143d881613d56565b82525050565b6143e781613d92565b82525050565b600061010082019050614403600083018b6143cf565b614410602083018a6143de565b61441d60408301896143cf565b61442a6060830188613f2f565b6144376080830187613c3e565b61444460a0830186613c3e565b61445160c0830185613c3e565b61445e60e0830184613c3e565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006144d860338361446b565b91506144e38261447c565b604082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b600061456a60238361446b565b91506145758261450e565b604082019050919050565b600060208201905081810360008301526145998161455d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145d6601f8361446b565b91506145e1826145a0565b602082019050919050565b60006020820190508181036000830152614605816145c9565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b600061464260118361446b565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b600061472060658361446b565b915061472b82614678565b608082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b600061478c601d8361446b565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147fc82613c34565b915061480783613c34565b925082820390508181111561481f5761481e6147c2565b5b92915050565b600060408201905061483a6000830185613f2f565b6148476020830184613c3e565b9392505050565b61485781613eb9565b811461486257600080fd5b50565b6000815190506148748161484e565b92915050565b6000602082840312156148905761488f613c68565b5b600061489e84828501614865565b91505092915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b600061490360338361446b565b915061490e826148a7565b604082019050919050565b60006020820190508181036000830152614932816148f6565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b600061499560368361446b565b91506149a082614939565b604082019050919050565b600060208201905081810360008301526149c481614988565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614a27603e8361446b565b9150614a32826149cb565b604082019050919050565b60006020820190508181036000830152614a5681614a1a565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614ab960258361446b565b9150614ac482614a5d565b604082019050919050565b60006020820190508181036000830152614ae881614aac565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614b4b60328361446b565b9150614b5682614aef565b604082019050919050565b60006020820190508181036000830152614b7a81614b3e565b9050919050565b600060ff82169050919050565b614b9781614b81565b8114614ba257600080fd5b50565b600081519050614bb481614b8e565b92915050565b600060208284031215614bd057614bcf613c68565b5b6000614bde84828501614ba5565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614c3e57808604811115614c1a57614c196147c2565b5b6001851615614c295780820291505b8081029050614c3785614be7565b9450614bfe565b94509492505050565b600082614c575760019050614d13565b81614c655760009050614d13565b8160018114614c7b5760028114614c8557614cb4565b6001915050614d13565b60ff841115614c9757614c966147c2565b5b8360020a915084821115614cae57614cad6147c2565b5b50614d13565b5060208310610133831016604e8410600b8410161715614ce95782820a905083811115614ce457614ce36147c2565b5b614d13565b614cf68484846001614bf4565b92509050818404811115614d0d57614d0c6147c2565b5b81810290505b9392505050565b6000614d2582613c34565b9150614d3083614b81565b9250614d5d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614c47565b905092915050565b6000614d7082613c34565b9150614d7b83613c34565b9250828202614d8981613c34565b91508282048414831517614da057614d9f6147c2565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614de182613c34565b9150614dec83613c34565b925082614dfc57614dfb614da7565b5b828204905092915050565b6000614e1282613c34565b9150614e1d83613c34565b9250828201905080821115614e3557614e346147c2565b5b92915050565b6000614e4682613c34565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e7857614e776147c2565b5b600182019050919050565b6000819050919050565b6000614ea8614ea3614e9e84614e83565b613fd5565b613c34565b9050919050565b614eb881614e8d565b82525050565b6000602082019050614ed36000830184614eaf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b6000614f9360348361446b565b9150614f9e82614f37565b604082019050919050565b60006020820190508181036000830152614fc281614f86565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b600061504b604d8361446b565b915061505682614fc9565b606082019050919050565b6000602082019050818103600083015261507a8161503e565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006150dd60308361446b565b91506150e882615081565b604082019050919050565b6000602082019050818103600083015261510c816150d0565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006151508385615113565b935061515d838584615124565b61516683615133565b840190509392505050565b6000602082019050818103600083015261518c818486615144565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006151cb600e8361446b565b91506151d682615195565b602082019050919050565b600060208201905081810360008301526151fa816151be565b9050919050565b60006060820190506152166000830186613f2f565b6152236020830185613f2f565b6152306040830184613c3e565b949350505050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061529460378361446b565b915061529f82615238565b604082019050919050565b600060208201905081810360008301526152c381615287565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b6000615326603c8361446b565b9150615331826152ca565b604082019050919050565b6000602082019050818103600083015261535581615319565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b60006153b860228361446b565b91506153c38261535c565b604082019050919050565b600060208201905081810360008301526153e7816153ab565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b600061544a60218361446b565b9150615455826153ee565b604082019050919050565b600060208201905081810360008301526154798161543d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006154dc60268361446b565b91506154e782615480565b604082019050919050565b6000602082019050818103600083015261550b816154cf565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061554860208361446b565b915061555382615512565b602082019050919050565b600060208201905081810360008301526155778161553b565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006155b460108361446b565b91506155bf8261557e565b602082019050919050565b600060208201905081810360008301526155e3816155a7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212201cdc9d5ba326b01aa0d9981853263ca20b434dbf4172c9f057a8b3e26cb89cc564736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613c4d565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613cd0565b610a75565b6040516103609190613c4d565b60405180910390f35b610383600480360381019061037e9190613cd0565b610ac1565b005b61039f600480360381019061039a9190613d29565b610b44565b005b6103bb60048036038101906103b69190613d29565b610b90565b005b6103d760048036038101906103d29190613d29565b610bd9565b005b6103f360048036038101906103ee9190613dda565b610eea565b005b6103fd61143f565b005b610407611888565b005b610423600480360381019061041e9190613e8c565b611a68565b005b61043f600480360381019061043a9190613cd0565b611ad4565b60405161044c9190613ed4565b60405180910390f35b61046f600480360381019061046a9190613d29565b611af1565b005b61048b60048036038101906104869190613eef565b611b3a565b6040516104989190613c4d565b60405180910390f35b6104bb60048036038101906104b69190613dda565b611b65565b005b6104d760048036038101906104d29190613cd0565b611db7565b6040516104e49190613f3e565b60405180910390f35b61050760048036038101906105029190613cd0565b611dea565b6040516105149190613ed4565b60405180910390f35b61053760048036038101906105329190613d29565b611e0a565b005b610541611e56565b60405161054e9190613ed4565b60405180910390f35b610571600480360381019061056c9190613cd0565b611e6d565b60405161057e9190613c4d565b60405180910390f35b6105a1600480360381019061059c9190613f59565b611eb9565b6040516105af929190613fac565b60405180910390f35b6105c0611f71565b005b6105ca611f85565b6040516105d79190614034565b60405180910390f35b6105fa60048036038101906105f59190613cd0565b611fab565b005b610604612084565b6040516106119190613c4d565b60405180910390f35b610634600480360381019061062f9190613cd0565b61208a565b6040516106419190613ed4565b60405180910390f35b61065261210b565b60405161065f919061410d565b60405180910390f35b610682600480360381019061067d9190614194565b6121f9565b005b61069e60048036038101906106999190614208565b6127eb565b005b6106a8612999565b6040516106b59190613ed4565b60405180910390f35b6106c66129d7565b6040516106d39190613f3e565b60405180910390f35b6106e46129ff565b6040516106f5959493929190614248565b60405180910390f35b61071860048036038101906107139190613cd0565b612a23565b005b610722612aa6565b60405161072f9190613ed4565b60405180910390f35b610752600480360381019061074d9190613d29565b612ae3565b005b61075c612ce1565b005b610766612e9b565b005b610770612f08565b60405161077d9190613f3e565b60405180910390f35b61078e612f2e565b60405161079b9190613c4d565b60405180910390f35b6107be60048036038101906107b9919061429b565b612f34565b005b6107c8612f5c565b005b6107d26131f2565b005b6107dc6133e6565b6040516107e991906143b4565b60405180910390f35b6107fa6133f9565b604051610807919061410d565b60405180910390f35b6108186134e7565b6040516108259190613c4d565b60405180910390f35b61084860048036038101906108439190613d29565b61352b565b005b610852613574565b005b61085c6135c9565b6040516108699190613c4d565b60405180910390f35b61087a6135cf565b6040516108879190613ed4565b60405180910390f35b6108aa60048036038101906108a59190613cd0565b61369a565b005b6108b461371d565b6040516108c19190613ed4565b60405180910390f35b6108e460048036038101906108df9190613cd0565b61375b565b6040516108f89897969594939291906143ed565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610946906144ee565b60405180910390fd5b600060048111156109635761096261433d565b5b600160159054906101000a900460ff1660048111156109855761098461433d565b5b14806109c45750600360048111156109a05761099f61433d565b5b600160159054906101000a900460ff1660048111156109c2576109c161433d565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614580565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a2761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b91906143b4565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac96137ff565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b399190613f3e565b60405180910390a150565b610b4c6137ff565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613c4d565b60405180910390a150565b610b986137ff565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613c4d565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c15906145ec565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6090614658565b60405180910390fd5b60001515610c8133600c61387d90919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90614736565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f906147a2565b60405180910390fd5b80600a54610d5691906147f1565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa91906147f1565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610e4d929190614825565b6020604051808303816000875af1158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e90919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610ed79190613c4d565b60405180910390a2600160008190555050565b600260005403610f2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f26906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610fc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fba90614919565b60405180910390fd5b60006004811115610fd757610fd661433d565b5b600160159054906101000a900460ff166004811115610ff957610ff861433d565b5b14806110385750600360048111156110145761101361433d565b5b600160159054906101000a900460ff1660048111156110365761103561433d565b5b145b8061107557506004808111156110515761105061433d565b5b600160159054906101000a900460ff1660048111156110735761107261433d565b5b145b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ab906149ab565b60405180910390fd5b600015156110cc33601061387d90919063ffffffff16565b15151461110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590614a3d565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea33600e6138ad90919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147e906144ee565b60405180910390fd5b6002600481111561149b5761149a61433d565b5b600160159054906101000a900460ff1660048111156114bd576114bc61433d565b5b146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f490614acf565b60405180910390fd5b600115156115096135cf565b15151461154b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154290614b61565b60405180910390fd5b6000611557600c6138dd565b905060005b818110156116df57600061157a82600c6138f290919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190614bba565b600a6116199190614d1a565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116699190614d65565b6116739190614dd6565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116c49190614e07565b925050819055505080806116d790614e3b565b91505061155c565b505b60006116ed600c6138dd565b11156117215761171b61170b6000600c6138f290919063ffffffff16565b600c61390c90919063ffffffff16565b506116e1565b61172b600e6138dd565b905060005b818110156117de5761175f61174f82600e6138f290919063ffffffff16565b600c6138ad90919063ffffffff16565b5060006014600061177a84600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806117d690614e3b565b915050611730565b50600360010160008154809291906117f590614e3b565b91905055506003600001544361180b9190614e07565b6003600201819055506000600160156101000a81548160ff0219169083600481111561183a5761183961433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff1660405161187d91906143b4565b60405180910390a150565b6002600054036118cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c4906145ec565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000811115611a5d576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016119ca929190614825565b6020604051808303816000875af11580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d919061487a565b503373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611a549190613c4d565b60405180910390a25b506001600081905550565b611a706137ff565b80600160156101000a81548160ff02191690836004811115611a9557611a9461433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611ac991906143b4565b60405180910390a150565b6000611aea82600c61387d90919063ffffffff16565b9050919050565b611af96137ff565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611b2f9190613c4d565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611e126137ff565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611e4b9190613c4d565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611f796137ff565b611f83600061393c565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe7906145ec565b60405180910390fd5b60026000819055506120006137ff565b61201481600e61390c90919063ffffffff16565b506120298160106138ad90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e9760006040516120719190614ebe565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120ec6134e7565b816000015410612100576001915050612106565b60009150505b919050565b60606000612119600c6138dd565b67ffffffffffffffff81111561213257612131614ed9565b5b6040519080825280602002602001820160405280156121605781602001602082028036833780820191505090505b509050600061216f600c6138dd565b905060005b818110156121f05761219081600c6138f290919063ffffffff16565b8382815181106121a3576121a2614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806121e890614e3b565b915050612174565b50819250505090565b60026000540361223e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612235906145ec565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fa9565b60405180910390fd5b61232d81600e61387d90919063ffffffff16565b61236c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236390615061565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c906150f3565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008154809291906124be90614e3b565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061258585600e61387d90919063ffffffff16565b801561259657506125958561208a565b5b15612774576125af85600e61390c90919063ffffffff16565b506125c48560106138ad90919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546126199190614d65565b6126239190614dd6565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461267791906147f1565b9250508190555080600a600082825461269091906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016126f29190613c4d565b600060405180830381600087803b15801561270c57600080fd5b505af1158015612720573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e978260405161276a9190613c4d565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa86866040516127d4929190615171565b60405180910390a450600160008190555050505050565b600260005403612830576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612827906145ec565b60405180910390fd5b60026000819055506128406137ff565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201600082825461289291906147f1565b9250508190555080600a60008282546128ab91906147f1565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161290d9190613c4d565b600060405180830381600087803b15801561292757600080fd5b505af115801561293b573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516129859190613c4d565b60405180910390a260016000819055505050565b6000600160048111156129af576129ae61433d565b5b600160159054906101000a900460ff1660048111156129d1576129d061433d565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612a2b6137ff565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a607581604051612a9b9190613f3e565b60405180910390a150565b6000806004811115612abb57612aba61433d565b5b600160159054906101000a900460ff166004811115612add57612adc61433d565b5b14905090565b600260005403612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f906145ec565b60405180910390fd5b600260008190555060008111612b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b6a906151e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401612bd293929190615201565b6020604051808303816000875af1158015612bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c15919061487a565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612c689190614e07565b9250508190555080600a6000828254612c819190614e07565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612cce9190613c4d565b60405180910390a2600160008190555050565b600260005403612d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1d906145ec565b60405180910390fd5b600260008190555060006004811115612d4257612d4161433d565b5b600160159054906101000a900460ff166004811115612d6457612d6361433d565b5b1480612da3575060036004811115612d7f57612d7e61433d565b5b600160159054906101000a900460ff166004811115612da157612da061433d565b5b145b80612de05750600480811115612dbc57612dbb61433d565b5b600160159054906101000a900460ff166004811115612dde57612ddd61433d565b5b145b612e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e16906152aa565b60405180910390fd5b612e3333600e61387d90919063ffffffff16565b15612e4e57612e4c33600e61390c90919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612ea36137ff565b6004600160156101000a81548160ff02191690836004811115612ec957612ec861433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612efe91906143b4565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612f3c6139ff565b612f4587612ae3565b612f53868686868686610eea565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612fd457612fd361433d565b5b600160159054906101000a900460ff166004811115612ff657612ff561433d565b5b14806130355750600260048111156130115761301061433d565b5b600160159054906101000a900460ff1660048111156130335761303261433d565b5b145b613074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306b9061533c565b60405180910390fd5b6001600360010154146130d55761309581600e61387d90919063ffffffff16565b6130d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cb906153ce565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a26131786135cf565b156131ef576002600160156101000a81548160ff021916908360048111156131a3576131a261433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516131e691906143b4565b60405180910390a15b50565b6003600401546003600201546132089190614e07565b43101561324a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613241906144ee565b60405180910390fd5b6001600481111561325e5761325d61433d565b5b600160159054906101000a900460ff1660048111156132805761327f61433d565b5b146132c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132b790615460565b60405180910390fd5b60006132cc600e6138dd565b905060005b81811015613357576000601460006132f384600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061334f90614e3b565b9150506132d1565b5060038001600081548092919061336d90614e3b565b91905055506003600160156101000a81548160ff021916908360048111156133985761339761433d565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516133db91906143b4565b60405180910390a150565b600160159054906101000a900460ff1681565b60606000613407600e6138dd565b67ffffffffffffffff8111156134205761341f614ed9565b5b60405190808252806020026020018201604052801561344e5781602001602082028036833780820191505090505b509050600061345d600e6138dd565b905060005b818110156134de5761347e81600e6138f290919063ffffffff16565b83828151811061349157613490614f08565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806134d690614e3b565b915050613462565b50819250505090565b600060026134f5600c6138dd565b116135035760019050613528565b60036002613511600c6138dd565b61351b9190614d65565b6135259190614dd6565b90505b90565b6135336137ff565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a5816040516135699190613c4d565b60405180910390a150565b6135bf601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6135c7611888565b565b60095481565b6000806000905060006135e2600e6138dd565b905060005b81811015613676576014600061360783600e6138f290919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561366357828061365f90614e3b565b9350505b808061366e90614e3b565b9150506135e7565b5061367f6134e7565b821061369057600192505050613697565b6000925050505b90565b6136a26137ff565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613711576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613708906154f2565b60405180910390fd5b61371a8161393c565b50565b6000600360048111156137335761373261433d565b5b600160159054906101000a900460ff1660048111156137555761375461433d565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b613807613a49565b73ffffffffffffffffffffffffffffffffffffffff166138256129d7565b73ffffffffffffffffffffffffffffffffffffffff161461387b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138729061555e565b60405180910390fd5b565b60006138a5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a51565b905092915050565b60006138d5836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a74565b905092915050565b60006138eb82600001613ae4565b9050919050565b60006139018360000183613af5565b60001c905092915050565b6000613934836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b20565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a07611e56565b15613a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a3e906155ca565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613a808383613a51565b613ad9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613ade565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613b0d57613b0c614f08565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613c28576000600182613b5291906147f1565b9050600060018660000180549050613b6a91906147f1565b9050818114613bd9576000866000018281548110613b8b57613b8a614f08565b5b9060005260206000200154905080876000018481548110613baf57613bae614f08565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613bed57613bec6155ea565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613c2e565b60009150505b92915050565b6000819050919050565b613c4781613c34565b82525050565b6000602082019050613c626000830184613c3e565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c9d82613c72565b9050919050565b613cad81613c92565b8114613cb857600080fd5b50565b600081359050613cca81613ca4565b92915050565b600060208284031215613ce657613ce5613c68565b5b6000613cf484828501613cbb565b91505092915050565b613d0681613c34565b8114613d1157600080fd5b50565b600081359050613d2381613cfd565b92915050565b600060208284031215613d3f57613d3e613c68565b5b6000613d4d84828501613d14565b91505092915050565b600063ffffffff82169050919050565b613d6f81613d56565b8114613d7a57600080fd5b50565b600081359050613d8c81613d66565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b613db781613d92565b8114613dc257600080fd5b50565b600081359050613dd481613dae565b92915050565b60008060008060008060c08789031215613df757613df6613c68565b5b6000613e0589828a01613d7d565b9650506020613e1689828a01613dc5565b9550506040613e2789828a01613d7d565b9450506060613e3889828a01613cbb565b9350506080613e4989828a01613d14565b92505060a0613e5a89828a01613d14565b9150509295509295509295565b60058110613e7457600080fd5b50565b600081359050613e8681613e67565b92915050565b600060208284031215613ea257613ea1613c68565b5b6000613eb084828501613e77565b91505092915050565b60008115159050919050565b613ece81613eb9565b82525050565b6000602082019050613ee96000830184613ec5565b92915050565b60008060408385031215613f0657613f05613c68565b5b6000613f1485828601613d14565b9250506020613f2585828601613cbb565b9150509250929050565b613f3881613c92565b82525050565b6000602082019050613f536000830184613f2f565b92915050565b600080600060608486031215613f7257613f71613c68565b5b6000613f8086828701613d14565b9350506020613f9186828701613cbb565b9250506040613fa286828701613cbb565b9150509250925092565b6000604082019050613fc16000830185613c3e565b613fce6020830184613ec5565b9392505050565b6000819050919050565b6000613ffa613ff5613ff084613c72565b613fd5565b613c72565b9050919050565b600061400c82613fdf565b9050919050565b600061401e82614001565b9050919050565b61402e81614013565b82525050565b60006020820190506140496000830184614025565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61408481613c92565b82525050565b6000614096838361407b565b60208301905092915050565b6000602082019050919050565b60006140ba8261404f565b6140c4818561405a565b93506140cf8361406b565b8060005b838110156141005781516140e7888261408a565b97506140f2836140a2565b9250506001810190506140d3565b5085935050505092915050565b6000602082019050818103600083015261412781846140af565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141545761415361412f565b5b8235905067ffffffffffffffff81111561417157614170614134565b5b60208301915083600182028301111561418d5761418c614139565b5b9250929050565b600080600080606085870312156141ae576141ad613c68565b5b60006141bc87828801613cbb565b94505060206141cd87828801613d14565b935050604085013567ffffffffffffffff8111156141ee576141ed613c6d565b5b6141fa8782880161413e565b925092505092959194509250565b6000806040838503121561421f5761421e613c68565b5b600061422d85828601613cbb565b925050602061423e85828601613d14565b9150509250929050565b600060a08201905061425d6000830188613c3e565b61426a6020830187613c3e565b6142776040830186613c3e565b6142846060830185613c3e565b6142916080830184613c3e565b9695505050505050565b600080600080600080600060e0888a0312156142ba576142b9613c68565b5b60006142c88a828b01613d14565b97505060206142d98a828b01613d7d565b96505060406142ea8a828b01613dc5565b95505060606142fb8a828b01613d7d565b945050608061430c8a828b01613cbb565b93505060a061431d8a828b01613d14565b92505060c061432e8a828b01613d14565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061437d5761437c61433d565b5b50565b600081905061438e8261436c565b919050565b600061439e82614380565b9050919050565b6143ae81614393565b82525050565b60006020820190506143c960008301846143a5565b92915050565b6143d881613d56565b82525050565b6143e781613d92565b82525050565b600061010082019050614403600083018b6143cf565b614410602083018a6143de565b61441d60408301896143cf565b61442a6060830188613f2f565b6144376080830187613c3e565b61444460a0830186613c3e565b61445160c0830185613c3e565b61445e60e0830184613c3e565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006144d860338361446b565b91506144e38261447c565b604082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b600061456a60238361446b565b91506145758261450e565b604082019050919050565b600060208201905081810360008301526145998161455d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145d6601f8361446b565b91506145e1826145a0565b602082019050919050565b60006020820190508181036000830152614605816145c9565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b600061464260118361446b565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b600061472060658361446b565b915061472b82614678565b608082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b600061478c601d8361446b565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006147fc82613c34565b915061480783613c34565b925082820390508181111561481f5761481e6147c2565b5b92915050565b600060408201905061483a6000830185613f2f565b6148476020830184613c3e565b9392505050565b61485781613eb9565b811461486257600080fd5b50565b6000815190506148748161484e565b92915050565b6000602082840312156148905761488f613c68565b5b600061489e84828501614865565b91505092915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b600061490360338361446b565b915061490e826148a7565b604082019050919050565b60006020820190508181036000830152614932816148f6565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b600061499560368361446b565b91506149a082614939565b604082019050919050565b600060208201905081810360008301526149c481614988565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614a27603e8361446b565b9150614a32826149cb565b604082019050919050565b60006020820190508181036000830152614a5681614a1a565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614ab960258361446b565b9150614ac482614a5d565b604082019050919050565b60006020820190508181036000830152614ae881614aac565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614b4b60328361446b565b9150614b5682614aef565b604082019050919050565b60006020820190508181036000830152614b7a81614b3e565b9050919050565b600060ff82169050919050565b614b9781614b81565b8114614ba257600080fd5b50565b600081519050614bb481614b8e565b92915050565b600060208284031215614bd057614bcf613c68565b5b6000614bde84828501614ba5565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614c3e57808604811115614c1a57614c196147c2565b5b6001851615614c295780820291505b8081029050614c3785614be7565b9450614bfe565b94509492505050565b600082614c575760019050614d13565b81614c655760009050614d13565b8160018114614c7b5760028114614c8557614cb4565b6001915050614d13565b60ff841115614c9757614c966147c2565b5b8360020a915084821115614cae57614cad6147c2565b5b50614d13565b5060208310610133831016604e8410600b8410161715614ce95782820a905083811115614ce457614ce36147c2565b5b614d13565b614cf68484846001614bf4565b92509050818404811115614d0d57614d0c6147c2565b5b81810290505b9392505050565b6000614d2582613c34565b9150614d3083614b81565b9250614d5d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614c47565b905092915050565b6000614d7082613c34565b9150614d7b83613c34565b9250828202614d8981613c34565b91508282048414831517614da057614d9f6147c2565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614de182613c34565b9150614dec83613c34565b925082614dfc57614dfb614da7565b5b828204905092915050565b6000614e1282613c34565b9150614e1d83613c34565b9250828201905080821115614e3557614e346147c2565b5b92915050565b6000614e4682613c34565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e7857614e776147c2565b5b600182019050919050565b6000819050919050565b6000614ea8614ea3614e9e84614e83565b613fd5565b613c34565b9050919050565b614eb881614e8d565b82525050565b6000602082019050614ed36000830184614eaf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b6000614f9360348361446b565b9150614f9e82614f37565b604082019050919050565b60006020820190508181036000830152614fc281614f86565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b600061504b604d8361446b565b915061505682614fc9565b606082019050919050565b6000602082019050818103600083015261507a8161503e565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006150dd60308361446b565b91506150e882615081565b604082019050919050565b6000602082019050818103600083015261510c816150d0565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006151508385615113565b935061515d838584615124565b61516683615133565b840190509392505050565b6000602082019050818103600083015261518c818486615144565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006151cb600e8361446b565b91506151d682615195565b602082019050919050565b600060208201905081810360008301526151fa816151be565b9050919050565b60006060820190506152166000830186613f2f565b6152236020830185613f2f565b6152306040830184613c3e565b949350505050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061529460378361446b565b915061529f82615238565b604082019050919050565b600060208201905081810360008301526152c381615287565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b6000615326603c8361446b565b9150615331826152ca565b604082019050919050565b6000602082019050818103600083015261535581615319565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b60006153b860228361446b565b91506153c38261535c565b604082019050919050565b600060208201905081810360008301526153e7816153ab565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b600061544a60218361446b565b9150615455826153ee565b604082019050919050565b600060208201905081810360008301526154798161543d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006154dc60268361446b565b91506154e782615480565b604082019050919050565b6000602082019050818103600083015261550b816154cf565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061554860208361446b565b915061555382615512565b602082019050919050565b600060208201905081810360008301526155778161553b565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006155b460108361446b565b91506155bf8261557e565b602082019050919050565b600060208201905081810360008301526155e3816155a7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212201cdc9d5ba326b01aa0d9981853263ca20b434dbf4172c9f057a8b3e26cb89cc564736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"EpochLengthSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"EpochTimeoutSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"KickPenaltyPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"MinimumStakeSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"ReadyForNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"ResolverContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"StakingTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"StateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"TokenRewardPerTokenPerEpochSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBurned","type":"uint256"}],"name":"ValidatorKickedFromNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reporter","type":"address"},{"indexed":true,"internalType":"address","name":"validatorStakerAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"reason","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"VotedToKickValidatorInNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"}],"name":"adminKickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"amountToBurn","type":"uint256"}],"name":"adminSlashValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"advanceEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"epochLength","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"retries","type":"uint256"},{"internalType":"uint256","name":"timeout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValidatorsInCurrentEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorsInNextEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochNumber","type":"uint256"},{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"address","name":"voterStakerAddress","type":"address"}],"name":"getVotingStatusToKickValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isActiveValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReadyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickPenaltyPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"reason","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"kickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nodeAddressToStakerAddress","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":"pauseEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"requestToJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestToLeave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolverContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"setEpochLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"setEpochState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"setEpochTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"setIpPortNodeAddressAndCommunicationPubKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"setKickPenaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"setResolverContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"setStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"setTokenRewardPerTokenPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"shouldKickValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signalReadyForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"stakeAndJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract ERC20Burnable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Staking.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenRewardPerTokenPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorCountForConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsInNextEpochAreLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votesToKickValidatorsInNextEpoch","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/localchain_31337/WLIT.json b/deployments/localchain_31337/WLIT.json deleted file mode 100644 index afc93e0..0000000 --- a/deployments/localchain_31337/WLIT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/WLIT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\ncontract WLIT {\\n string public name = \\\"Wrapped Lit\\\";\\n string public symbol = \\\"WLIT\\\";\\n uint8 public decimals = 18;\\n\\n event Approval(address indexed src, address indexed guy, uint wad);\\n event Transfer(address indexed src, address indexed dst, uint wad);\\n event Deposit(address indexed dst, uint wad);\\n event Withdrawal(address indexed src, uint wad);\\n\\n mapping(address => uint) public balanceOf;\\n mapping(address => mapping(address => uint)) public allowance;\\n\\n fallback() external payable {\\n deposit();\\n }\\n\\n receive() external payable {\\n deposit();\\n }\\n\\n function deposit() public payable {\\n balanceOf[msg.sender] += msg.value;\\n emit Deposit(msg.sender, msg.value);\\n }\\n\\n function withdraw(uint wad) public {\\n require(balanceOf[msg.sender] >= wad);\\n balanceOf[msg.sender] -= wad;\\n payable(msg.sender).transfer(wad);\\n emit Withdrawal(msg.sender, wad);\\n }\\n\\n function totalSupply() public view returns (uint) {\\n return address(this).balance;\\n }\\n\\n function approve(address guy, uint wad) public returns (bool) {\\n allowance[msg.sender][guy] = wad;\\n emit Approval(msg.sender, guy, wad);\\n return true;\\n }\\n\\n function transfer(address dst, uint wad) public returns (bool) {\\n return transferFrom(msg.sender, dst, wad);\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint wad\\n ) public returns (bool) {\\n require(balanceOf[src] >= wad);\\n\\n if (\\n src != msg.sender && allowance[src][msg.sender] != type(uint256).max\\n ) {\\n require(allowance[src][msg.sender] >= wad);\\n allowance[src][msg.sender] -= wad;\\n }\\n\\n balanceOf[src] -= wad;\\n balanceOf[dst] += wad;\\n\\n emit Transfer(src, dst, wad);\\n\\n return true;\\n }\\n\\n function burn(uint256 amount) internal virtual {\\n transferFrom(msg.sender, address(0), amount);\\n }\\n\\n function burnFrom(address account, uint256 amount) public virtual {\\n transferFrom(account, address(0), amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0","bytecode":"0x60806040526040518060400160405280600b81526020017f57726170706564204c6974000000000000000000000000000000000000000000815250600090816200004a91906200033c565b506040518060400160405280600481526020017f574c495400000000000000000000000000000000000000000000000000000000815250600190816200009191906200033c565b506012600260006101000a81548160ff021916908360ff160217905550348015620000bb57600080fd5b5062000423565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200014457607f821691505b6020821081036200015a5762000159620000fc565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620001c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000185565b620001d0868362000185565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200021d620002176200021184620001e8565b620001f2565b620001e8565b9050919050565b6000819050919050565b6200023983620001fc565b62000251620002488262000224565b84845462000192565b825550505050565b600090565b6200026862000259565b620002758184846200022e565b505050565b5b818110156200029d57620002916000826200025e565b6001810190506200027b565b5050565b601f821115620002ec57620002b68162000160565b620002c18462000175565b81016020851015620002d1578190505b620002e9620002e08562000175565b8301826200027a565b50505b505050565b600082821c905092915050565b60006200031160001984600802620002f1565b1980831691505092915050565b60006200032c8383620002fe565b9150826002028217905092915050565b6200034782620000c2565b67ffffffffffffffff811115620003635762000362620000cd565b5b6200036f82546200012b565b6200037c828285620002a1565b600060209050601f831160018114620003b457600084156200039f578287015190505b620003ab85826200031e565b8655506200041b565b601f198416620003c48662000160565b60005b82811015620003ee57848901518255600182019150602085019450602081019050620003c7565b868310156200040e57848901516200040a601f891682620002fe565b8355505b6001600288020188555050505b505050505050565b610f0980620004336000396000f3fe6080604052600436106100ab5760003560e01c806370a082311161006457806370a08231146101e857806379cc67901461022557806395d89b411461024e578063a9059cbb14610279578063d0e30db0146102b6578063dd62ed3e146102c0576100ba565b806306fdde03146100c4578063095ea7b3146100ef57806318160ddd1461012c57806323b872dd146101575780632e1a7d4d14610194578063313ce567146101bd576100ba565b366100ba576100b86102fd565b005b6100c26102fd565b005b3480156100d057600080fd5b506100d96103a3565b6040516100e69190610b5d565b60405180910390f35b3480156100fb57600080fd5b5061011660048036038101906101119190610c18565b610431565b6040516101239190610c73565b60405180910390f35b34801561013857600080fd5b50610141610523565b60405161014e9190610c9d565b60405180910390f35b34801561016357600080fd5b5061017e60048036038101906101799190610cb8565b61052b565b60405161018b9190610c73565b60405180910390f35b3480156101a057600080fd5b506101bb60048036038101906101b69190610d0b565b61088f565b005b3480156101c957600080fd5b506101d26109c9565b6040516101df9190610d54565b60405180910390f35b3480156101f457600080fd5b5061020f600480360381019061020a9190610d6f565b6109dc565b60405161021c9190610c9d565b60405180910390f35b34801561023157600080fd5b5061024c60048036038101906102479190610c18565b6109f4565b005b34801561025a57600080fd5b50610263610a05565b6040516102709190610b5d565b60405180910390f35b34801561028557600080fd5b506102a0600480360381019061029b9190610c18565b610a93565b6040516102ad9190610c73565b60405180910390f35b6102be6102fd565b005b3480156102cc57600080fd5b506102e760048036038101906102e29190610d9c565b610aa8565b6040516102f49190610c9d565b60405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461034c9190610e0b565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516103999190610c9d565b60405180910390a2565b600080546103b090610e6e565b80601f01602080910402602001604051908101604052809291908181526020018280546103dc90610e6e565b80156104295780601f106103fe57610100808354040283529160200191610429565b820191906000526020600020905b81548152906001019060200180831161040c57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105119190610c9d565b60405180910390a36001905092915050565b600047905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561057957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415801561065157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156107735781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106df57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461076b9190610e9f565b925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107c29190610e9f565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108189190610e0b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161087c9190610c9d565b60405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156108db57600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461092a9190610e9f565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610977573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109be9190610c9d565b60405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b610a008260008361052b565b505050565b60018054610a1290610e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3e90610e6e565b8015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b820191906000526020600020905b815481529060010190602001808311610a6e57829003601f168201915b505050505081565b6000610aa033848461052b565b905092915050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b07578082015181840152602081019050610aec565b60008484015250505050565b6000601f19601f8301169050919050565b6000610b2f82610acd565b610b398185610ad8565b9350610b49818560208601610ae9565b610b5281610b13565b840191505092915050565b60006020820190508181036000830152610b778184610b24565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610baf82610b84565b9050919050565b610bbf81610ba4565b8114610bca57600080fd5b50565b600081359050610bdc81610bb6565b92915050565b6000819050919050565b610bf581610be2565b8114610c0057600080fd5b50565b600081359050610c1281610bec565b92915050565b60008060408385031215610c2f57610c2e610b7f565b5b6000610c3d85828601610bcd565b9250506020610c4e85828601610c03565b9150509250929050565b60008115159050919050565b610c6d81610c58565b82525050565b6000602082019050610c886000830184610c64565b92915050565b610c9781610be2565b82525050565b6000602082019050610cb26000830184610c8e565b92915050565b600080600060608486031215610cd157610cd0610b7f565b5b6000610cdf86828701610bcd565b9350506020610cf086828701610bcd565b9250506040610d0186828701610c03565b9150509250925092565b600060208284031215610d2157610d20610b7f565b5b6000610d2f84828501610c03565b91505092915050565b600060ff82169050919050565b610d4e81610d38565b82525050565b6000602082019050610d696000830184610d45565b92915050565b600060208284031215610d8557610d84610b7f565b5b6000610d9384828501610bcd565b91505092915050565b60008060408385031215610db357610db2610b7f565b5b6000610dc185828601610bcd565b9250506020610dd285828601610bcd565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e1682610be2565b9150610e2183610be2565b9250828201905080821115610e3957610e38610ddc565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e8657607f821691505b602082108103610e9957610e98610e3f565b5b50919050565b6000610eaa82610be2565b9150610eb583610be2565b9250828203905081811115610ecd57610ecc610ddc565b5b9291505056fea26469706673582212201c0f017d93f99b09bce924b932df35eb4c2850e4bf949d92ca05ee8c3e899dc164736f6c63430008110033","deployedBytecode":"0x6080604052600436106100ab5760003560e01c806370a082311161006457806370a08231146101e857806379cc67901461022557806395d89b411461024e578063a9059cbb14610279578063d0e30db0146102b6578063dd62ed3e146102c0576100ba565b806306fdde03146100c4578063095ea7b3146100ef57806318160ddd1461012c57806323b872dd146101575780632e1a7d4d14610194578063313ce567146101bd576100ba565b366100ba576100b86102fd565b005b6100c26102fd565b005b3480156100d057600080fd5b506100d96103a3565b6040516100e69190610b5d565b60405180910390f35b3480156100fb57600080fd5b5061011660048036038101906101119190610c18565b610431565b6040516101239190610c73565b60405180910390f35b34801561013857600080fd5b50610141610523565b60405161014e9190610c9d565b60405180910390f35b34801561016357600080fd5b5061017e60048036038101906101799190610cb8565b61052b565b60405161018b9190610c73565b60405180910390f35b3480156101a057600080fd5b506101bb60048036038101906101b69190610d0b565b61088f565b005b3480156101c957600080fd5b506101d26109c9565b6040516101df9190610d54565b60405180910390f35b3480156101f457600080fd5b5061020f600480360381019061020a9190610d6f565b6109dc565b60405161021c9190610c9d565b60405180910390f35b34801561023157600080fd5b5061024c60048036038101906102479190610c18565b6109f4565b005b34801561025a57600080fd5b50610263610a05565b6040516102709190610b5d565b60405180910390f35b34801561028557600080fd5b506102a0600480360381019061029b9190610c18565b610a93565b6040516102ad9190610c73565b60405180910390f35b6102be6102fd565b005b3480156102cc57600080fd5b506102e760048036038101906102e29190610d9c565b610aa8565b6040516102f49190610c9d565b60405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461034c9190610e0b565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040516103999190610c9d565b60405180910390a2565b600080546103b090610e6e565b80601f01602080910402602001604051908101604052809291908181526020018280546103dc90610e6e565b80156104295780601f106103fe57610100808354040283529160200191610429565b820191906000526020600020905b81548152906001019060200180831161040c57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105119190610c9d565b60405180910390a36001905092915050565b600047905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561057957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415801561065157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156107735781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106df57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461076b9190610e9f565b925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107c29190610e9f565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108189190610e0b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161087c9190610c9d565b60405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156108db57600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461092a9190610e9f565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610977573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109be9190610c9d565b60405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b610a008260008361052b565b505050565b60018054610a1290610e6e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3e90610e6e565b8015610a8b5780601f10610a6057610100808354040283529160200191610a8b565b820191906000526020600020905b815481529060010190602001808311610a6e57829003601f168201915b505050505081565b6000610aa033848461052b565b905092915050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b07578082015181840152602081019050610aec565b60008484015250505050565b6000601f19601f8301169050919050565b6000610b2f82610acd565b610b398185610ad8565b9350610b49818560208601610ae9565b610b5281610b13565b840191505092915050565b60006020820190508181036000830152610b778184610b24565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610baf82610b84565b9050919050565b610bbf81610ba4565b8114610bca57600080fd5b50565b600081359050610bdc81610bb6565b92915050565b6000819050919050565b610bf581610be2565b8114610c0057600080fd5b50565b600081359050610c1281610bec565b92915050565b60008060408385031215610c2f57610c2e610b7f565b5b6000610c3d85828601610bcd565b9250506020610c4e85828601610c03565b9150509250929050565b60008115159050919050565b610c6d81610c58565b82525050565b6000602082019050610c886000830184610c64565b92915050565b610c9781610be2565b82525050565b6000602082019050610cb26000830184610c8e565b92915050565b600080600060608486031215610cd157610cd0610b7f565b5b6000610cdf86828701610bcd565b9350506020610cf086828701610bcd565b9250506040610d0186828701610c03565b9150509250925092565b600060208284031215610d2157610d20610b7f565b5b6000610d2f84828501610c03565b91505092915050565b600060ff82169050919050565b610d4e81610d38565b82525050565b6000602082019050610d696000830184610d45565b92915050565b600060208284031215610d8557610d84610b7f565b5b6000610d9384828501610bcd565b91505092915050565b60008060408385031215610db357610db2610b7f565b5b6000610dc185828601610bcd565b9250506020610dd285828601610bcd565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e1682610be2565b9150610e2183610be2565b9250828201905080821115610e3957610e38610ddc565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e8657607f821691505b602082108103610e9957610e98610e3f565b5b50919050565b6000610eaa82610be2565b9150610eb583610be2565b9250828203905081811115610ecd57610ecc610ddc565b5b9291505056fea26469706673582212201c0f017d93f99b09bce924b932df35eb4c2850e4bf949d92ca05ee8c3e899dc164736f6c63430008110033","abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/AccessControlConditions.json b/deployments/mumbai_80001/AccessControlConditions.json deleted file mode 100644 index 11eb442..0000000 --- a/deployments/mumbai_80001/AccessControlConditions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/AccessControlConditions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract AccessControlConditions is Ownable, ReentrancyGuard {\\n /* ========== STRUCTS ========== */\\n struct StoredCondition {\\n uint256 value;\\n uint256 securityHash;\\n uint256 chainId;\\n bool permanent;\\n address creator;\\n }\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(uint256 => StoredCondition) public storedConditions;\\n address public signer;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n signer = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function getCondition(uint256 key)\\n external\\n view\\n returns (StoredCondition memory)\\n {\\n return storedConditions[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent\\n ) external nonReentrant {\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n msg.sender\\n );\\n }\\n\\n function storeConditionWithSigner(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) external nonReentrant {\\n require(\\n msg.sender == signer,\\n \\\"Only signer can call storeConditionsWithSigner.\\\"\\n );\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n }\\n\\n function setSigner(address newSigner) public onlyOwner {\\n signer = newSigner;\\n }\\n\\n /* ========== PRIVATE FUNCTIONS ========== */\\n\\n function _storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) private {\\n require(key != 0, \\\"Key must not be zero\\\");\\n if (storedConditions[key].creator != address(0)) {\\n // this is an update\\n require(\\n storedConditions[key].creator == creatorAddress,\\n \\\"Only the condition creator can update it\\\"\\n );\\n require(\\n storedConditions[key].permanent == false,\\n \\\"This condition was stored with the Permanent flag and cannot be updated\\\"\\n );\\n require(msg.sender != signer, \\\"Signer cannot update conditions\\\");\\n }\\n storedConditions[key] = StoredCondition(\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n\\n emit ConditionStored(key, value, chainId, permanent, creatorAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ConditionStored(\\n uint256 indexed key,\\n uint256 value,\\n uint256 chainId,\\n bool permanent,\\n address creator\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x173077cfA497AE6179370D0cabF937245B509624","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261007a60201b60201c565b61008260201b60201c565b6001808190555033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610146565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61128b806101556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"permanent","type":"bool"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"ConditionStored","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":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getCondition","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"internalType":"struct AccessControlConditions.StoredCondition","name":"","type":"tuple"}],"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":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"}],"name":"storeCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"storeConditionWithSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"storedConditions","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/Allowlist.json b/deployments/mumbai_80001/Allowlist.json deleted file mode 100644 index 74089dd..0000000 --- a/deployments/mumbai_80001/Allowlist.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Allowlist.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Allowlist is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(bytes32 => bool) public allowedItems;\\n EnumerableSet.AddressSet admins;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n admins.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function isAllowed(bytes32 key) external view returns (bool) {\\n return allowedItems[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function setAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = true;\\n emit ItemAllowed(key);\\n }\\n\\n function setNotAllowed(bytes32 key) external {\\n require(admins.contains(msg.sender), \\\"Not an admin\\\");\\n allowedItems[key] = false;\\n emit ItemNotAllowed(key);\\n }\\n\\n function addAdmin(address newAdmin) public onlyOwner {\\n admins.add(newAdmin);\\n emit AdminAdded(newAdmin);\\n }\\n\\n function removeAdmin(address newAdmin) public onlyOwner {\\n admins.remove(newAdmin);\\n emit AdminRemoved(newAdmin);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ItemAllowed(bytes32 indexed key);\\n event ItemNotAllowed(bytes32 indexed key);\\n event AdminAdded(address indexed newAdmin);\\n event AdminRemoved(address indexed newAdmin);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x97FA7458E454E2927Eb2968Eb7305b5017c9FFa2","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261005260201b60201c565b61005a60201b60201c565b6001808190555061004c33600361011e60201b6104da1790919060201c565b506101ed565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600061014c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61015460201b60201c565b905092915050565b600061016683836101ca60201b60201c565b6101bf5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506101c4565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b610c2a806101fc6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637875529511610066578063787552951461010a578063865815971461013a5780638767d9aa146101565780638da5cb5b14610172578063f2fde38b1461019057610093565b80631785f53c1461009857806352f97536146100b457806370480275146100e4578063715018a614610100575b600080fd5b6100b260048036038101906100ad91906108be565b6101ac565b005b6100ce60048036038101906100c99190610921565b61020f565b6040516100db9190610969565b60405180910390f35b6100fe60048036038101906100f991906108be565b61022f565b005b610108610292565b005b610124600480360381019061011f9190610921565b6102a6565b6040516101319190610969565b60405180910390f35b610154600480360381019061014f9190610921565b6102d0565b005b610170600480360381019061016b9190610921565b61037f565b005b61017a61042e565b6040516101879190610993565b60405180910390f35b6101aa60048036038101906101a591906108be565b610457565b005b6101b461050a565b6101c881600361058890919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f60405160405180910390a250565b60026020528060005260406000206000915054906101000a900460ff1681565b61023761050a565b61024b8160036104da90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44d6d25963f097ad14f29f06854a01f575648a1ef82f30e562ccd3889717e33960405160405180910390a250565b61029a61050a565b6102a460006105b8565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b6102e433600361067c90919063ffffffff16565b610323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031a90610a0b565b60405180910390fd5b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a250565b61039333600361067c90919063ffffffff16565b6103d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c990610a0b565b60405180910390fd5b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61045f61050a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c590610a9d565b60405180910390fd5b6104d7816105b8565b50565b6000610502836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6106ac565b905092915050565b61051261071c565b73ffffffffffffffffffffffffffffffffffffffff1661053061042e565b73ffffffffffffffffffffffffffffffffffffffff1614610586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057d90610b09565b60405180910390fd5b565b60006105b0836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610724565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b610838565b905092915050565b60006106b88383610838565b610711578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610716565b600090505b92915050565b600033905090565b6000808360010160008481526020019081526020016000205490506000811461082c5760006001826107569190610b62565b905060006001866000018054905061076e9190610b62565b90508181146107dd57600086600001828154811061078f5761078e610b96565b5b90600052602060002001549050808760000184815481106107b3576107b2610b96565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806107f1576107f0610bc5565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610832565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061088b82610860565b9050919050565b61089b81610880565b81146108a657600080fd5b50565b6000813590506108b881610892565b92915050565b6000602082840312156108d4576108d361085b565b5b60006108e2848285016108a9565b91505092915050565b6000819050919050565b6108fe816108eb565b811461090957600080fd5b50565b60008135905061091b816108f5565b92915050565b6000602082840312156109375761093661085b565b5b60006109458482850161090c565b91505092915050565b60008115159050919050565b6109638161094e565b82525050565b600060208201905061097e600083018461095a565b92915050565b61098d81610880565b82525050565b60006020820190506109a86000830184610984565b92915050565b600082825260208201905092915050565b7f4e6f7420616e2061646d696e0000000000000000000000000000000000000000600082015250565b60006109f5600c836109ae565b9150610a00826109bf565b602082019050919050565b60006020820190508181036000830152610a24816109e8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610a876026836109ae565b9150610a9282610a2b565b604082019050919050565b60006020820190508181036000830152610ab681610a7a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610af36020836109ae565b9150610afe82610abd565b602082019050919050565b60006020820190508181036000830152610b2281610ae6565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b6d82610b29565b9150610b7883610b29565b9250828203905081811115610b9057610b8f610b33565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220782bcee247518d12bbf963f047ecddddf375375724e4a5c743c2facf935b0b9864736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemNotAllowed","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":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"allowedItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/ContractResolver.json b/deployments/mumbai_80001/ContractResolver.json deleted file mode 100644 index b731c15..0000000 --- a/deployments/mumbai_80001/ContractResolver.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/ContractResolver.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract ContractResolver is AccessControl {\\n /* ========== TYPE DEFINITIONS ========== */\\n\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n bytes32 public constant RELEASE_REGISTER_CONTRACT =\\n keccak256(\\\"RELEASE_REGISTER\\\");\\n bytes32 public constant STAKING_CONTRACT = keccak256(\\\"STAKING\\\");\\n bytes32 public constant MULTI_SENDER_CONTRACT = keccak256(\\\"MULTI_SENDER\\\");\\n bytes32 public constant LIT_TOKEN_CONTRACT = keccak256(\\\"LIT_TOKEN\\\");\\n bytes32 public constant ACCESS_CONTROL_CONTRACT =\\n keccak256(\\\"ACCESS_CONTROL\\\");\\n bytes32 public constant PUB_KEY_ROUTER_CONTRACT =\\n keccak256(\\\"PUB_KEY_ROUTER\\\");\\n bytes32 public constant PKP_NFT_CONTRACT = keccak256(\\\"PKP_NFT\\\");\\n bytes32 public constant RATE_LIMIT_NFT_CONTRACT =\\n keccak256(\\\"RATE_LIMIT_NFT\\\");\\n bytes32 public constant PKP_HELPER_CONTRACT = keccak256(\\\"PKP_HELPER\\\");\\n bytes32 public constant PKP_PERMISSIONS_CONTRACT =\\n keccak256(\\\"PKP_PERMISSIONS\\\");\\n bytes32 public constant PKP_NFT_METADATA_CONTRACT =\\n keccak256(\\\"PKP_NFT_METADATA\\\");\\n bytes32 public constant ALLOWLIST_CONTRACT = keccak256(\\\"ALLOWLIST\\\");\\n\\n enum Env {\\n Dev,\\n Test,\\n Prod\\n }\\n\\n /* ========== ERRORS ========== */\\n\\n /// The ADMIN role is required to use this function\\n error AdminRoleRequired();\\n\\n /* ========== EVENTS ========== */\\n\\n event AllowedEnvAdded(Env env);\\n\\n event AllowedEnvRemoved(Env env);\\n\\n event SetContract(bytes32 typ, Env env, address addr);\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(Env => bool) allowedEnvs;\\n mapping(bytes32 => mapping(Env => address)) public typeAddresses;\\n\\n /* ========== CONSTRUCTOR ========== */\\n\\n constructor(Env env) {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n\\n allowedEnvs[env] = true;\\n\\n emit AllowedEnvAdded(env);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// add an allowed env\\n function addAllowedEnv(Env env) public {\\n // Check roles\\n if (!hasRole(ADMIN_ROLE, msg.sender)) {\\n revert AdminRoleRequired();\\n }\\n\\n allowedEnvs[env] = true;\\n\\n emit AllowedEnvAdded(env);\\n }\\n\\n /// remove an allowed env\\n function removeAllowedEnv(Env env) public {\\n // Check roles\\n if (!hasRole(ADMIN_ROLE, msg.sender)) {\\n revert AdminRoleRequired();\\n }\\n\\n delete allowedEnvs[env];\\n\\n emit AllowedEnvRemoved(env);\\n }\\n\\n /// set the active address for a deployed contract\\n function setContract(bytes32 typ, Env env, address addr) public {\\n // Check roles\\n if (!hasRole(ADMIN_ROLE, msg.sender)) {\\n revert AdminRoleRequired();\\n }\\n\\n // Ensure the env is available\\n require(\\n allowedEnvs[env] == true,\\n \\\"The provided Env is not valid for this contract\\\"\\n );\\n\\n // Set the contract address\\n typeAddresses[typ][env] = addr;\\n\\n // Emit events\\n emit SetContract(typ, env, addr);\\n }\\n\\n function setAdmin(address newAdmin) public {\\n if (!hasRole(ADMIN_ROLE, msg.sender)) {\\n revert AdminRoleRequired();\\n }\\n _grantRole(ADMIN_ROLE, newAdmin);\\n _revokeRole(ADMIN_ROLE, msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// Returns the matching contract address for a given type and env\\n function getContract(bytes32 typ, Env env) public view returns (address) {\\n return (typeAddresses[typ][env]);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x95705851AA07e4e0d4eA58275a0D8a3DBAF6a4e3","bytecode":"0x60806040523480156200001157600080fd5b5060405162001f7938038062001f79833981810160405281019062000037919062000358565b620000697fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42336200013060201b60201c565b6200009b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42806200014660201b60201c565b6001806000836002811115620000b657620000b56200038a565b5b6002811115620000cb57620000ca6200038a565b5b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f839ad2743d4062df579edf3818f642b71ee0688a35d6bc4438ef5314cece8015816040516200012191906200040a565b60405180910390a15062000427565b620001428282620001a960201b60201c565b5050565b600062000159836200029a60201b60201c565b905081600080858152602001908152602001600020600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b620001bb8282620002b960201b60201c565b6200029657600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200023b6200032360201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000806000838152602001908152602001600020600101549050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b600381106200033e57600080fd5b50565b600081519050620003528162000330565b92915050565b6000602082840312156200037157620003706200032b565b5b6000620003818482850162000341565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110620003cd57620003cc6200038a565b5b50565b6000819050620003e082620003b9565b919050565b6000620003f282620003d0565b9050919050565b6200040481620003e5565b82525050565b6000602082019050620004216000830184620003f9565b92915050565b611b4280620004376000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c806375b238fc116100de578063977a807011610097578063d547741f11610071578063d547741f14610475578063da19ddfb14610491578063df380693146104af578063f8ae93b4146104cd5761018e565b8063977a80701461041b578063a217fddf14610439578063ad1c8a86146104575761018e565b806375b238fc146103455780637cadf69f146103635780638deb3893146103815780638e8dfd161461039d5780639072f838146103cd57806391d14854146103eb5761018e565b80632f2ff15d1161014b57806350673a5a1161012557806350673a5a146102d357806351ad0a80146102f1578063704b6c021461030d57806374bc8139146103295761018e565b80632f2ff15d1461026b57806336568abe146102875780633ebf7985146102a35761018e565b806301ffc9a71461019357806316f76bbf146101c3578063248a9ca3146101e15780632668f305146102115780632c0b8bf71461022f5780632e4885e81461024d575b600080fd5b6101ad60048036038101906101a891906112f3565b6104eb565b6040516101ba919061133b565b60405180910390f35b6101cb610565565b6040516101d8919061136f565b60405180910390f35b6101fb60048036038101906101f691906113b6565b610589565b604051610208919061136f565b60405180910390f35b6102196105a8565b604051610226919061136f565b60405180910390f35b6102376105cc565b604051610244919061136f565b60405180910390f35b6102556105f0565b604051610262919061136f565b60405180910390f35b61028560048036038101906102809190611441565b610614565b005b6102a1600480360381019061029c9190611441565b610635565b005b6102bd60048036038101906102b891906114a6565b6106b8565b6040516102ca91906114f5565b60405180910390f35b6102db6106fa565b6040516102e8919061136f565b60405180910390f35b61030b60048036038101906103069190611510565b61071e565b005b61032760048036038101906103229190611563565b6108d0565b005b610343600480360381019061033e9190611590565b610987565b005b61034d610a70565b60405161035a919061136f565b60405180910390f35b61036b610a94565b604051610378919061136f565b60405180910390f35b61039b60048036038101906103969190611590565b610ab8565b005b6103b760048036038101906103b291906114a6565b610b99565b6040516103c491906114f5565b60405180910390f35b6103d5610c0c565b6040516103e2919061136f565b60405180910390f35b61040560048036038101906104009190611441565b610c30565b604051610412919061133b565b60405180910390f35b610423610c9a565b604051610430919061136f565b60405180910390f35b610441610cbe565b60405161044e919061136f565b60405180910390f35b61045f610cc5565b60405161046c919061136f565b60405180910390f35b61048f600480360381019061048a9190611441565b610ce9565b005b610499610d0a565b6040516104a6919061136f565b60405180910390f35b6104b7610d2e565b6040516104c4919061136f565b60405180910390f35b6104d5610d52565b6040516104e2919061136f565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061055e575061055d82610d76565b5b9050919050565b7ff14f431dadc82e7dbc5e379f71234e5735c9187e4327a7c6ac014d55d1b7727a81565b6000806000838152602001908152602001600020600101549050919050565b7fb1f79813bc7630a52ae948bc99781397e409d0dd3521953bf7d8d7a2db6147f781565b7fb7b4fde9944d3c13e9a78835431c33a5084d90a7f0c73def76d7886315fe87b081565b7fb931b2719aeb2a65a5035fa0a190bfdc4c8622ce8cbff7a3d1ab42531fb1a91881565b61061d82610589565b61062681610de0565b6106308383610df4565b505050565b61063d610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a190611640565b60405180910390fd5b6106b48282610edc565b5050565b60026020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f6450fc880933ecbac6591cb5b043b20f0f2a1452c46acdd5919b2bdafc37439c81565b6107487fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b61077e576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600115156001600084600281111561079957610798611660565b5b60028111156107ab576107aa611660565b5b815260200190815260200160002060009054906101000a900460ff16151514610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080090611701565b60405180910390fd5b8060026000858152602001908152602001600020600084600281111561083257610831611660565b5b600281111561084457610843611660565b5b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f33f014890f109229bbcf8dd47204c153a2c0ff1c572a61de220d10336530f53d8383836040516108c393929190611769565b60405180910390a1505050565b6108fa7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b610930576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61095a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4282610df4565b6109847fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610edc565b50565b6109b17fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b6109e7576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018060008360028111156109ff576109fe611660565b5b6002811115610a1157610a10611660565b5b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f839ad2743d4062df579edf3818f642b71ee0688a35d6bc4438ef5314cece801581604051610a6591906117a0565b60405180910390a150565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b7f74845de37cfabd357633214b47fa91ccd19b05b7c5a08ac22c187f811fb62bca81565b610ae27fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b610b18576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016000826002811115610b2f57610b2e611660565b5b6002811115610b4157610b40611660565b5b815260200190815260200160002060006101000a81549060ff02191690557f3f178f17dae6caf8ca09c4857502baf7744e8597de42d6596476fe9e06b8ad4781604051610b8e91906117a0565b60405180910390a150565b6000600260008481526020019081526020016000206000836002811115610bc357610bc2611660565b5b6002811115610bd557610bd4611660565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b7f54953c23068b8fc4c0736301b50f10027d6b469327de1fd42841a5072b1bcebe81565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7f27d764ea2a4a3865434bbf4a391110149644be31448f3479fd15b4438875576581565b6000801b81565b7f3a68dbfd8bbb64015c42bc131c388dea7965e28c1004d09b39f59500c3a763ec81565b610cf282610589565b610cfb81610de0565b610d058383610edc565b505050565b7f080909c18c958ce5a2d36481697824e477319323d03154ceba3b78f28a61887b81565b7fb4bf999b68d8085dbbf7a0ec2f5a2d660873935bdf1ed08eb421ac6dcbc0036281565b7fdd5b9b8a5e8e01f2962ed7e983d58fe32e1f66aa88dd7ab30770fa9b77da724381565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610df181610dec610ed4565b610fbd565b50565b610dfe8282610c30565b610ed057600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610e75610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b610ee68282610c30565b15610fb957600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610f5e610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b610fc78282610c30565b61105657610fec8173ffffffffffffffffffffffffffffffffffffffff16601461105a565b610ffa8360001c602061105a565b60405160200161100b9291906118c4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104d9190611948565b60405180910390fd5b5050565b60606000600283600261106d91906119a3565b61107791906119e5565b67ffffffffffffffff8111156110905761108f611a19565b5b6040519080825280601f01601f1916602001820160405280156110c25781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106110fa576110f9611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061115e5761115d611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261119e91906119a3565b6111a891906119e5565b90505b6001811115611248577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106111ea576111e9611a48565b5b1a60f81b82828151811061120157611200611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061124190611a77565b90506111ab565b506000841461128c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390611aec565b60405180910390fd5b8091505092915050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6112d08161129b565b81146112db57600080fd5b50565b6000813590506112ed816112c7565b92915050565b60006020828403121561130957611308611296565b5b6000611317848285016112de565b91505092915050565b60008115159050919050565b61133581611320565b82525050565b6000602082019050611350600083018461132c565b92915050565b6000819050919050565b61136981611356565b82525050565b60006020820190506113846000830184611360565b92915050565b61139381611356565b811461139e57600080fd5b50565b6000813590506113b08161138a565b92915050565b6000602082840312156113cc576113cb611296565b5b60006113da848285016113a1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061140e826113e3565b9050919050565b61141e81611403565b811461142957600080fd5b50565b60008135905061143b81611415565b92915050565b6000806040838503121561145857611457611296565b5b6000611466858286016113a1565b92505060206114778582860161142c565b9150509250929050565b6003811061148e57600080fd5b50565b6000813590506114a081611481565b92915050565b600080604083850312156114bd576114bc611296565b5b60006114cb858286016113a1565b92505060206114dc85828601611491565b9150509250929050565b6114ef81611403565b82525050565b600060208201905061150a60008301846114e6565b92915050565b60008060006060848603121561152957611528611296565b5b6000611537868287016113a1565b935050602061154886828701611491565b92505060406115598682870161142c565b9150509250925092565b60006020828403121561157957611578611296565b5b60006115878482850161142c565b91505092915050565b6000602082840312156115a6576115a5611296565b5b60006115b484828501611491565b91505092915050565b600082825260208201905092915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b600061162a602f836115bd565b9150611635826115ce565b604082019050919050565b600060208201905081810360008301526116598161161d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f5468652070726f766964656420456e76206973206e6f742076616c696420666f60008201527f72207468697320636f6e74726163740000000000000000000000000000000000602082015250565b60006116eb602f836115bd565b91506116f68261168f565b604082019050919050565b6000602082019050818103600083015261171a816116de565b9050919050565b6003811061173257611731611660565b5b50565b600081905061174382611721565b919050565b600061175382611735565b9050919050565b61176381611748565b82525050565b600060608201905061177e6000830186611360565b61178b602083018561175a565b61179860408301846114e6565b949350505050565b60006020820190506117b5600083018461175a565b92915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006117fc6017836117bb565b9150611807826117c6565b601782019050919050565b600081519050919050565b60005b8381101561183b578082015181840152602081019050611820565b60008484015250505050565b600061185282611812565b61185c81856117bb565b935061186c81856020860161181d565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b60006118ae6011836117bb565b91506118b982611878565b601182019050919050565b60006118cf826117ef565b91506118db8285611847565b91506118e6826118a1565b91506118f28284611847565b91508190509392505050565b6000601f19601f8301169050919050565b600061191a82611812565b61192481856115bd565b935061193481856020860161181d565b61193d816118fe565b840191505092915050565b60006020820190508181036000830152611962818461190f565b905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006119ae8261196a565b91506119b98361196a565b92508282026119c78161196a565b915082820484148315176119de576119dd611974565b5b5092915050565b60006119f08261196a565b91506119fb8361196a565b9250828201905080821115611a1357611a12611974565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000611a828261196a565b915060008203611a9557611a94611974565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000611ad66020836115bd565b9150611ae182611aa0565b602082019050919050565b60006020820190508181036000830152611b0581611ac9565b905091905056fea2646970667358221220eeff3c18be2c1108ea6f011de277f426651939f8dc25121ba3eb0a73ac98799064736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061018e5760003560e01c806375b238fc116100de578063977a807011610097578063d547741f11610071578063d547741f14610475578063da19ddfb14610491578063df380693146104af578063f8ae93b4146104cd5761018e565b8063977a80701461041b578063a217fddf14610439578063ad1c8a86146104575761018e565b806375b238fc146103455780637cadf69f146103635780638deb3893146103815780638e8dfd161461039d5780639072f838146103cd57806391d14854146103eb5761018e565b80632f2ff15d1161014b57806350673a5a1161012557806350673a5a146102d357806351ad0a80146102f1578063704b6c021461030d57806374bc8139146103295761018e565b80632f2ff15d1461026b57806336568abe146102875780633ebf7985146102a35761018e565b806301ffc9a71461019357806316f76bbf146101c3578063248a9ca3146101e15780632668f305146102115780632c0b8bf71461022f5780632e4885e81461024d575b600080fd5b6101ad60048036038101906101a891906112f3565b6104eb565b6040516101ba919061133b565b60405180910390f35b6101cb610565565b6040516101d8919061136f565b60405180910390f35b6101fb60048036038101906101f691906113b6565b610589565b604051610208919061136f565b60405180910390f35b6102196105a8565b604051610226919061136f565b60405180910390f35b6102376105cc565b604051610244919061136f565b60405180910390f35b6102556105f0565b604051610262919061136f565b60405180910390f35b61028560048036038101906102809190611441565b610614565b005b6102a1600480360381019061029c9190611441565b610635565b005b6102bd60048036038101906102b891906114a6565b6106b8565b6040516102ca91906114f5565b60405180910390f35b6102db6106fa565b6040516102e8919061136f565b60405180910390f35b61030b60048036038101906103069190611510565b61071e565b005b61032760048036038101906103229190611563565b6108d0565b005b610343600480360381019061033e9190611590565b610987565b005b61034d610a70565b60405161035a919061136f565b60405180910390f35b61036b610a94565b604051610378919061136f565b60405180910390f35b61039b60048036038101906103969190611590565b610ab8565b005b6103b760048036038101906103b291906114a6565b610b99565b6040516103c491906114f5565b60405180910390f35b6103d5610c0c565b6040516103e2919061136f565b60405180910390f35b61040560048036038101906104009190611441565b610c30565b604051610412919061133b565b60405180910390f35b610423610c9a565b604051610430919061136f565b60405180910390f35b610441610cbe565b60405161044e919061136f565b60405180910390f35b61045f610cc5565b60405161046c919061136f565b60405180910390f35b61048f600480360381019061048a9190611441565b610ce9565b005b610499610d0a565b6040516104a6919061136f565b60405180910390f35b6104b7610d2e565b6040516104c4919061136f565b60405180910390f35b6104d5610d52565b6040516104e2919061136f565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061055e575061055d82610d76565b5b9050919050565b7ff14f431dadc82e7dbc5e379f71234e5735c9187e4327a7c6ac014d55d1b7727a81565b6000806000838152602001908152602001600020600101549050919050565b7fb1f79813bc7630a52ae948bc99781397e409d0dd3521953bf7d8d7a2db6147f781565b7fb7b4fde9944d3c13e9a78835431c33a5084d90a7f0c73def76d7886315fe87b081565b7fb931b2719aeb2a65a5035fa0a190bfdc4c8622ce8cbff7a3d1ab42531fb1a91881565b61061d82610589565b61062681610de0565b6106308383610df4565b505050565b61063d610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a190611640565b60405180910390fd5b6106b48282610edc565b5050565b60026020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f6450fc880933ecbac6591cb5b043b20f0f2a1452c46acdd5919b2bdafc37439c81565b6107487fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b61077e576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600115156001600084600281111561079957610798611660565b5b60028111156107ab576107aa611660565b5b815260200190815260200160002060009054906101000a900460ff16151514610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080090611701565b60405180910390fd5b8060026000858152602001908152602001600020600084600281111561083257610831611660565b5b600281111561084457610843611660565b5b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f33f014890f109229bbcf8dd47204c153a2c0ff1c572a61de220d10336530f53d8383836040516108c393929190611769565b60405180910390a1505050565b6108fa7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b610930576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61095a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4282610df4565b6109847fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610edc565b50565b6109b17fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b6109e7576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018060008360028111156109ff576109fe611660565b5b6002811115610a1157610a10611660565b5b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f839ad2743d4062df579edf3818f642b71ee0688a35d6bc4438ef5314cece801581604051610a6591906117a0565b60405180910390a150565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b7f74845de37cfabd357633214b47fa91ccd19b05b7c5a08ac22c187f811fb62bca81565b610ae27fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4233610c30565b610b18576040517fc890f84a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016000826002811115610b2f57610b2e611660565b5b6002811115610b4157610b40611660565b5b815260200190815260200160002060006101000a81549060ff02191690557f3f178f17dae6caf8ca09c4857502baf7744e8597de42d6596476fe9e06b8ad4781604051610b8e91906117a0565b60405180910390a150565b6000600260008481526020019081526020016000206000836002811115610bc357610bc2611660565b5b6002811115610bd557610bd4611660565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b7f54953c23068b8fc4c0736301b50f10027d6b469327de1fd42841a5072b1bcebe81565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7f27d764ea2a4a3865434bbf4a391110149644be31448f3479fd15b4438875576581565b6000801b81565b7f3a68dbfd8bbb64015c42bc131c388dea7965e28c1004d09b39f59500c3a763ec81565b610cf282610589565b610cfb81610de0565b610d058383610edc565b505050565b7f080909c18c958ce5a2d36481697824e477319323d03154ceba3b78f28a61887b81565b7fb4bf999b68d8085dbbf7a0ec2f5a2d660873935bdf1ed08eb421ac6dcbc0036281565b7fdd5b9b8a5e8e01f2962ed7e983d58fe32e1f66aa88dd7ab30770fa9b77da724381565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610df181610dec610ed4565b610fbd565b50565b610dfe8282610c30565b610ed057600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610e75610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b610ee68282610c30565b15610fb957600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610f5e610ed4565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b610fc78282610c30565b61105657610fec8173ffffffffffffffffffffffffffffffffffffffff16601461105a565b610ffa8360001c602061105a565b60405160200161100b9291906118c4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104d9190611948565b60405180910390fd5b5050565b60606000600283600261106d91906119a3565b61107791906119e5565b67ffffffffffffffff8111156110905761108f611a19565b5b6040519080825280601f01601f1916602001820160405280156110c25781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106110fa576110f9611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061115e5761115d611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261119e91906119a3565b6111a891906119e5565b90505b6001811115611248577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106111ea576111e9611a48565b5b1a60f81b82828151811061120157611200611a48565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061124190611a77565b90506111ab565b506000841461128c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390611aec565b60405180910390fd5b8091505092915050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6112d08161129b565b81146112db57600080fd5b50565b6000813590506112ed816112c7565b92915050565b60006020828403121561130957611308611296565b5b6000611317848285016112de565b91505092915050565b60008115159050919050565b61133581611320565b82525050565b6000602082019050611350600083018461132c565b92915050565b6000819050919050565b61136981611356565b82525050565b60006020820190506113846000830184611360565b92915050565b61139381611356565b811461139e57600080fd5b50565b6000813590506113b08161138a565b92915050565b6000602082840312156113cc576113cb611296565b5b60006113da848285016113a1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061140e826113e3565b9050919050565b61141e81611403565b811461142957600080fd5b50565b60008135905061143b81611415565b92915050565b6000806040838503121561145857611457611296565b5b6000611466858286016113a1565b92505060206114778582860161142c565b9150509250929050565b6003811061148e57600080fd5b50565b6000813590506114a081611481565b92915050565b600080604083850312156114bd576114bc611296565b5b60006114cb858286016113a1565b92505060206114dc85828601611491565b9150509250929050565b6114ef81611403565b82525050565b600060208201905061150a60008301846114e6565b92915050565b60008060006060848603121561152957611528611296565b5b6000611537868287016113a1565b935050602061154886828701611491565b92505060406115598682870161142c565b9150509250925092565b60006020828403121561157957611578611296565b5b60006115878482850161142c565b91505092915050565b6000602082840312156115a6576115a5611296565b5b60006115b484828501611491565b91505092915050565b600082825260208201905092915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b600061162a602f836115bd565b9150611635826115ce565b604082019050919050565b600060208201905081810360008301526116598161161d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f5468652070726f766964656420456e76206973206e6f742076616c696420666f60008201527f72207468697320636f6e74726163740000000000000000000000000000000000602082015250565b60006116eb602f836115bd565b91506116f68261168f565b604082019050919050565b6000602082019050818103600083015261171a816116de565b9050919050565b6003811061173257611731611660565b5b50565b600081905061174382611721565b919050565b600061175382611735565b9050919050565b61176381611748565b82525050565b600060608201905061177e6000830186611360565b61178b602083018561175a565b61179860408301846114e6565b949350505050565b60006020820190506117b5600083018461175a565b92915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006117fc6017836117bb565b9150611807826117c6565b601782019050919050565b600081519050919050565b60005b8381101561183b578082015181840152602081019050611820565b60008484015250505050565b600061185282611812565b61185c81856117bb565b935061186c81856020860161181d565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b60006118ae6011836117bb565b91506118b982611878565b601182019050919050565b60006118cf826117ef565b91506118db8285611847565b91506118e6826118a1565b91506118f28284611847565b91508190509392505050565b6000601f19601f8301169050919050565b600061191a82611812565b61192481856115bd565b935061193481856020860161181d565b61193d816118fe565b840191505092915050565b60006020820190508181036000830152611962818461190f565b905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006119ae8261196a565b91506119b98361196a565b92508282026119c78161196a565b915082820484148315176119de576119dd611974565b5b5092915050565b60006119f08261196a565b91506119fb8361196a565b9250828201905080821115611a1357611a12611974565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000611a828261196a565b915060008203611a9557611a94611974565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000611ad66020836115bd565b9150611ae182611aa0565b602082019050919050565b60006020820190508181036000830152611b0581611ac9565b905091905056fea2646970667358221220eeff3c18be2c1108ea6f011de277f426651939f8dc25121ba3eb0a73ac98799064736f6c63430008110033","abi":[{"inputs":[{"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AdminRoleRequired","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"name":"AllowedEnvAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"name":"AllowedEnvRemoved","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":"bytes32","name":"typ","type":"bytes32"},{"indexed":false,"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"},{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"SetContract","type":"event"},{"inputs":[],"name":"ACCESS_CONTROL_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ALLOWLIST_CONTRACT","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":"LIT_TOKEN_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MULTI_SENDER_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PKP_HELPER_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PKP_NFT_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PKP_NFT_METADATA_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PKP_PERMISSIONS_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUB_KEY_ROUTER_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_LIMIT_NFT_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RELEASE_REGISTER_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_CONTRACT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"name":"addAllowedEnv","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"typ","type":"bytes32"},{"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"name":"getContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"}],"name":"removeAllowedEnv","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":"newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"typ","type":"bytes32"},{"internalType":"enum ContractResolver.Env","name":"env","type":"uint8"},{"internalType":"address","name":"addr","type":"address"}],"name":"setContract","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":"bytes32","name":"","type":"bytes32"},{"internalType":"enum ContractResolver.Env","name":"","type":"uint8"}],"name":"typeAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/LITToken.json b/deployments/mumbai_80001/LITToken.json deleted file mode 100644 index c6bc3ea..0000000 --- a/deployments/mumbai_80001/LITToken.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xAC75982c51E545910F39b61F350eC784930f46B0","bytecode":"0x6101606040523480156200001257600080fd5b5060405162005abe38038062005abe833981810160405281019062000038919062000640565b6040518060400160405280600c81526020017f4c69742050726f746f636f6c0000000000000000000000000000000000000000815250806040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250836040518060400160405280600c81526020017f4c69742050726f746f636f6c00000000000000000000000000000000000000008152506040518060400160405280600381526020017f4c495400000000000000000000000000000000000000000000000000000000008152508160049081620001239190620008e2565b508060059081620001359190620008e2565b505050600081116200017e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001759062000a2a565b60405180910390fd5b8060808181525050506000600660006101000a81548160ff02191690831515021790555060008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508261010081815250508161012081815250504660c081815250506200020c818484620003c960201b60201c565b60a081815250503073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1681525050806101408181525050505050505050620002887fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42336200040560201b60201c565b620002ba7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9336200040560201b60201c565b620002ec7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a336200040560201b60201c565b6200033e7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc97fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec426200041b60201b60201c565b620003707fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42806200041b60201b60201c565b620003c27f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec426200041b60201b60201c565b5062000b1a565b60008383834630604051602001620003e695949392919062000abd565b6040516020818303038152906040528051906020012090509392505050565b6200041782826200047e60201b60201c565b5050565b60006200042e836200056f60201b60201c565b905081600080858152602001908152602001600020600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b6200049082826200058e60201b60201c565b6200056b57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555062000510620005f860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000806000838152602001908152602001600020600101549050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b6000819050919050565b6200061a8162000605565b81146200062657600080fd5b50565b6000815190506200063a816200060f565b92915050565b60006020828403121562000659576200065862000600565b5b6000620006698482850162000629565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620006f457607f821691505b6020821081036200070a5762000709620006ac565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620007747fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000735565b62000780868362000735565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620007c3620007bd620007b78462000605565b62000798565b62000605565b9050919050565b6000819050919050565b620007df83620007a2565b620007f7620007ee82620007ca565b84845462000742565b825550505050565b600090565b6200080e620007ff565b6200081b818484620007d4565b505050565b5b8181101562000843576200083760008262000804565b60018101905062000821565b5050565b601f82111562000892576200085c8162000710565b620008678462000725565b8101602085101562000877578190505b6200088f620008868562000725565b83018262000820565b50505b505050565b600082821c905092915050565b6000620008b76000198460080262000897565b1980831691505092915050565b6000620008d28383620008a4565b9150826002028217905092915050565b620008ed8262000672565b67ffffffffffffffff8111156200090957620009086200067d565b5b620009158254620006db565b6200092282828562000847565b600060209050601f8311600181146200095a576000841562000945578287015190505b620009518582620008c4565b865550620009c1565b601f1984166200096a8662000710565b60005b8281101562000994578489015182556001820191506020850194506020810190506200096d565b86831015620009b45784890151620009b0601f891682620008a4565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f45524332304361707065643a2063617020697320300000000000000000000000600082015250565b600062000a12601583620009c9565b915062000a1f82620009da565b602082019050919050565b6000602082019050818103600083015262000a458162000a03565b9050919050565b6000819050919050565b62000a618162000a4c565b82525050565b62000a728162000605565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000aa58262000a78565b9050919050565b62000ab78162000a98565b82525050565b600060a08201905062000ad4600083018862000a56565b62000ae3602083018762000a56565b62000af2604083018662000a56565b62000b01606083018562000a67565b62000b10608083018462000aac565b9695505050505050565b60805160a05160c05160e051610100516101205161014051614f4962000b756000396000611c7b01526000611cbd01526000611c9c01526000611bd101526000611c2701526000611c50015260006109810152614f496000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b578063a217fddf116100b8578063d53913931161007c578063d539139314610714578063d547741f14610732578063dd62ed3e1461074e578063e63ab1e91461077e578063f1127ed81461079c5761023d565b8063a217fddf1461065e578063a457c2d71461067c578063a9059cbb146106ac578063c3cda520146106dc578063d505accf146106f85761023d565b80638456cb59116100ff5780638456cb59146105a65780638e539e8c146105b057806391d14854146105e057806395d89b41146106105780639ab24eb01461062e5761023d565b80636fcfff45146104dc57806370a082311461050c57806375b238fc1461053c57806379cc67901461055a5780637ecebe00146105765761023d565b80633644e515116101c957806340c10f191161018d57806340c10f191461043a57806342966c6814610456578063587cde1e146104725780635c19a95c146104a25780635c975abb146104be5761023d565b80633644e5151461039657806336568abe146103b457806339509351146103d05780633a46b1a8146104005780633f4ba83a146104305761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a578063355274ea146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613352565b6107cc565b604051610269919061339a565b60405180910390f35b61027a610846565b6040516102879190613445565b60405180910390f35b6102aa60048036038101906102a591906134fb565b6108d8565b6040516102b7919061339a565b60405180910390f35b6102c86108fb565b6040516102d5919061354a565b60405180910390f35b6102f860048036038101906102f39190613565565b610905565b604051610305919061339a565b60405180910390f35b610328600480360381019061032391906135ee565b610934565b604051610335919061362a565b60405180910390f35b61035860048036038101906103539190613645565b610953565b005b610362610974565b60405161036f91906136a1565b60405180910390f35b61038061097d565b60405161038d919061354a565b60405180910390f35b61039e6109a5565b6040516103ab919061362a565b60405180910390f35b6103ce60048036038101906103c99190613645565b6109b4565b005b6103ea60048036038101906103e591906134fb565b610a37565b6040516103f7919061339a565b60405180910390f35b61041a600480360381019061041591906134fb565b610a6e565b604051610427919061354a565b60405180910390f35b610438610b02565b005b610454600480360381019061044f91906134fb565b610b7c565b005b610470600480360381019061046b91906136bc565b610bf3565b005b61048c600480360381019061048791906136e9565b610c07565b6040516104999190613725565b60405180910390f35b6104bc60048036038101906104b791906136e9565b610c70565b005b6104c6610c84565b6040516104d3919061339a565b60405180910390f35b6104f660048036038101906104f191906136e9565b610c9b565b604051610503919061375f565b60405180910390f35b610526600480360381019061052191906136e9565b610cef565b604051610533919061354a565b60405180910390f35b610544610d38565b604051610551919061362a565b60405180910390f35b610574600480360381019061056f91906134fb565b610d5c565b005b610590600480360381019061058b91906136e9565b610d7c565b60405161059d919061354a565b60405180910390f35b6105ae610dcc565b005b6105ca60048036038101906105c591906136bc565b610e46565b6040516105d7919061354a565b60405180910390f35b6105fa60048036038101906105f59190613645565b610e9c565b604051610607919061339a565b60405180910390f35b610618610f06565b6040516106259190613445565b60405180910390f35b610648600480360381019061064391906136e9565b610f98565b604051610655919061354a565b60405180910390f35b6106666110a9565b604051610673919061362a565b60405180910390f35b610696600480360381019061069191906134fb565b6110b0565b6040516106a3919061339a565b60405180910390f35b6106c660048036038101906106c191906134fb565b611127565b6040516106d3919061339a565b60405180910390f35b6106f660048036038101906106f191906137a6565b61114a565b005b610712600480360381019061070d9190613833565b61124e565b005b61071c611390565b604051610729919061362a565b60405180910390f35b61074c60048036038101906107479190613645565b6113b4565b005b610768600480360381019061076391906138d5565b6113d5565b604051610775919061354a565b60405180910390f35b61078661145c565b604051610793919061362a565b60405180910390f35b6107b660048036038101906107b19190613941565b611480565b6040516107c391906139f6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083f575061083e82611590565b5b9050919050565b60606004805461085590613a40565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613a40565b80156108ce5780601f106108a3576101008083540402835291602001916108ce565b820191906000526020600020905b8154815290600101906020018083116108b157829003601f168201915b5050505050905090565b6000806108e36115fa565b90506108f0818585611602565b600191505092915050565b6000600354905090565b6000806109106115fa565b905061091d8582856117cb565b610928858585611857565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61095c82610934565b61096581611ad9565b61096f8383611aed565b505050565b60006012905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60006109af611bcd565b905090565b6109bc6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2090613ae3565b60405180910390fd5b610a338282611ce7565b5050565b600080610a426115fa565b9050610a63818585610a5485896113d5565b610a5e9190613b32565b611602565b600191505092915050565b6000438210610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990613bb2565b60405180910390fd5b610afa600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083611dc8565b905092915050565b610b337f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b2e6115fa565b610e9c565b610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613c44565b60405180910390fd5b610b7a611ed4565b565b610ba67ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc933610e9c565b610be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdc90613cb0565b60405180910390fd5b610bef8282611f37565b5050565b610c04610bfe6115fa565b82611f45565b50565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6115fa565b82611f53565b50565b6000600660009054906101000a900460ff16905090565b6000610ce8600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061206d565b9050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b610d6e82610d686115fa565b836117cb565b610d788282611f45565b5050565b6000610dc5600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120c0565b9050919050565b610dfd7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610df86115fa565b610e9c565b610e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3390613d42565b60405180910390fd5b610e446120ce565b565b6000438210610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8190613bb2565b60405180910390fd5b610e95600b83611dc8565b9050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060058054610f1590613a40565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4190613a40565b8015610f8e5780601f10610f6357610100808354040283529160200191610f8e565b820191906000526020600020905b815481529060010190602001808311610f7157829003601f168201915b5050505050905090565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461108057600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826110349190613d62565b8154811061104557611044613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611083565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110bb6115fa565b905060006110c982866113d5565b90508381101561110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590613e37565b60405180910390fd5b61111b8286868403611602565b60019250505092915050565b6000806111326115fa565b905061113f818585611857565b600191505092915050565b8342111561118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118490613ea3565b60405180910390fd5b60006111ef6111e77fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111cc9493929190613ec3565b60405160208183030381529060405280519060200120612131565b85858561214b565b90506111fa81612176565b861461123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613f54565b60405180910390fd5b6112458188611f53565b50505050505050565b83421115611291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128890613fc0565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112c08c612176565b896040516020016112d696959493929190613fe0565b60405160208183030381529060405280519060200120905060006112f982612131565b905060006113098287878761214b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113709061408d565b60405180910390fd5b6113848a8a8a611602565b50505050505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6113bd82610934565b6113c681611ad9565b6113d08383611ce7565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6114886132b7565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106114df576114de613d96565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611671576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116689061411f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d7906141b1565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117be919061354a565b60405180910390a3505050565b60006117d784846113d5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118515781811015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183a9061421d565b60405180910390fd5b6118508484848403611602565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906142af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192c90614341565b60405180910390fd5b6119408383836121d4565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156119c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119be906143d3565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a5c9190613b32565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611ac0919061354a565b60405180910390a3611ad38484846121e4565b50505050565b611aea81611ae56115fa565b6121f4565b50565b611af78282610e9c565b611bc957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611b6e6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611c4957507f000000000000000000000000000000000000000000000000000000000000000046145b15611c76577f00000000000000000000000000000000000000000000000000000000000000009050611ce4565b611ce17f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612291565b90505b90565b611cf18282610e9c565b15611dc457600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611d696115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b81811015611e47576000611de982846122cb565b905084868281548110611dff57611dfe613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff161115611e3157809250611e41565b600181611e3e9190613b32565b91505b50611dd5565b60008214611ea95784600183611e5d9190613d62565b81548110611e6e57611e6d613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611eac565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b611edc6122f1565b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611f206115fa565b604051611f2d9190613725565b60405180910390a1565b611f41828261233a565b5050565b611f4f82826123c7565b5050565b6000611f5e83610c07565b90506000611f6b84610cef565b905082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46120678284836123e5565b50505050565b600063ffffffff80168211156120b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120af90614465565b60405180910390fd5b819050919050565b600081600001549050919050565b6120d66125de565b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861211a6115fa565b6040516121279190613725565b60405180910390a1565b600061214461213e611bcd565b83612628565b9050919050565b600080600061215c8787878761265b565b9150915061216981612767565b8192505050949350505050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506121c3816120c0565b91506121ce81612933565b50919050565b6121df838383612949565b505050565b6121ef838383612949565b505050565b6121fe8282610e9c565b61228d576122238173ffffffffffffffffffffffffffffffffffffffff1660146129a1565b6122318360001c60206129a1565b604051602001612242929190614559565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122849190613445565b60405180910390fd5b5050565b600083838346306040516020016122ac959493929190614593565b6040516020818303038152906040528051906020012090509392505050565b600060028284186122dc9190614615565b8284166122e99190613b32565b905092915050565b6122f9610c84565b612338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232f90614692565b60405180910390fd5b565b6123448282612bdd565b61234c612c47565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123726108fb565b11156123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123aa90614724565b60405180910390fd5b6123c1600b612c6b83612c81565b50505050565b6123d18282612ef9565b6123df600b6130d183612c81565b50505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156124215750600081115b156125d957600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146124ff576000806124a8600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206130d185612c81565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516124f4929190614744565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146125d857600080612581600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c6b85612c81565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516125cd929190614744565b60405180910390a250505b5b505050565b6125e6610c84565b15612626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261d906147b9565b60405180910390fd5b565b6000828260405160200161263d929190614846565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561269657600060039150915061275e565b601b8560ff16141580156126ae5750601c8560ff1614155b156126c057600060049150915061275e565b6000600187878787604051600081526020016040526040516126e5949392919061487d565b6020604051602081039080840390855afa158015612707573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127555760006001925092505061275e565b80600092509250505b94509492505050565b6000600481111561277b5761277a6148c2565b5b81600481111561278e5761278d6148c2565b5b031561293057600160048111156127a8576127a76148c2565b5b8160048111156127bb576127ba6148c2565b5b036127fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f29061493d565b60405180910390fd5b6002600481111561280f5761280e6148c2565b5b816004811115612822576128216148c2565b5b03612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149a9565b60405180910390fd5b60036004811115612876576128756148c2565b5b816004811115612889576128886148c2565b5b036128c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c090614a3b565b60405180910390fd5b6004808111156128dc576128db6148c2565b5b8160048111156128ef576128ee6148c2565b5b0361292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614acd565b60405180910390fd5b5b50565b6001816000016000828254019250508190555050565b6129548383836130e7565b61295c610c84565b1561299c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299390614b5f565b60405180910390fd5b505050565b6060600060028360026129b49190614b7f565b6129be9190613b32565b67ffffffffffffffff8111156129d7576129d6614bc1565b5b6040519080825280601f01601f191660200182016040528015612a095781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a4157612a40613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612aa557612aa4613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ae59190614b7f565b612aef9190613b32565b90505b6001811115612b8f577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b3157612b30613d96565b5b1a60f81b828281518110612b4857612b47613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612b8890614bf0565b9050612af2565b5060008414612bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bca90614c65565b60405180910390fd5b8091505092915050565b612be561097d565b81612bee6108fb565b612bf89190613b32565b1115612c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3090614cd1565b60405180910390fd5b612c4382826130ec565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008183612c799190613b32565b905092915050565b60008060008580549050905060008114612cef5785600182612ca39190613d62565b81548110612cb457612cb3613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612cf2565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612d2083858763ffffffff16565b9150600081118015612d7357504386600183612d3c9190613d62565b81548110612d4d57612d4c613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612e0057612d818261324c565b86600183612d8f9190613d62565b81548110612da057612d9f613d96565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612ef0565b856040518060400160405280612e154361206d565b63ffffffff168152602001612e298561324c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5f90614d63565b60405180910390fd5b612f74826000836121d4565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff290614df5565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008282546130539190613d62565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130b8919061354a565b60405180910390a36130cc836000846121e4565b505050565b600081836130df9190613d62565b905092915050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361315b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315290614e61565b60405180910390fd5b613167600083836121d4565b80600360008282546131799190613b32565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131cf9190613b32565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613234919061354a565b60405180910390a3613248600083836121e4565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156132af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a690614ef3565b60405180910390fd5b819050919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61332f816132fa565b811461333a57600080fd5b50565b60008135905061334c81613326565b92915050565b600060208284031215613368576133676132f5565b5b60006133768482850161333d565b91505092915050565b60008115159050919050565b6133948161337f565b82525050565b60006020820190506133af600083018461338b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133ef5780820151818401526020810190506133d4565b60008484015250505050565b6000601f19601f8301169050919050565b6000613417826133b5565b61342181856133c0565b93506134318185602086016133d1565b61343a816133fb565b840191505092915050565b6000602082019050818103600083015261345f818461340c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061349282613467565b9050919050565b6134a281613487565b81146134ad57600080fd5b50565b6000813590506134bf81613499565b92915050565b6000819050919050565b6134d8816134c5565b81146134e357600080fd5b50565b6000813590506134f5816134cf565b92915050565b60008060408385031215613512576135116132f5565b5b6000613520858286016134b0565b9250506020613531858286016134e6565b9150509250929050565b613544816134c5565b82525050565b600060208201905061355f600083018461353b565b92915050565b60008060006060848603121561357e5761357d6132f5565b5b600061358c868287016134b0565b935050602061359d868287016134b0565b92505060406135ae868287016134e6565b9150509250925092565b6000819050919050565b6135cb816135b8565b81146135d657600080fd5b50565b6000813590506135e8816135c2565b92915050565b600060208284031215613604576136036132f5565b5b6000613612848285016135d9565b91505092915050565b613624816135b8565b82525050565b600060208201905061363f600083018461361b565b92915050565b6000806040838503121561365c5761365b6132f5565b5b600061366a858286016135d9565b925050602061367b858286016134b0565b9150509250929050565b600060ff82169050919050565b61369b81613685565b82525050565b60006020820190506136b66000830184613692565b92915050565b6000602082840312156136d2576136d16132f5565b5b60006136e0848285016134e6565b91505092915050565b6000602082840312156136ff576136fe6132f5565b5b600061370d848285016134b0565b91505092915050565b61371f81613487565b82525050565b600060208201905061373a6000830184613716565b92915050565b600063ffffffff82169050919050565b61375981613740565b82525050565b60006020820190506137746000830184613750565b92915050565b61378381613685565b811461378e57600080fd5b50565b6000813590506137a08161377a565b92915050565b60008060008060008060c087890312156137c3576137c26132f5565b5b60006137d189828a016134b0565b96505060206137e289828a016134e6565b95505060406137f389828a016134e6565b945050606061380489828a01613791565b935050608061381589828a016135d9565b92505060a061382689828a016135d9565b9150509295509295509295565b600080600080600080600060e0888a031215613852576138516132f5565b5b60006138608a828b016134b0565b97505060206138718a828b016134b0565b96505060406138828a828b016134e6565b95505060606138938a828b016134e6565b94505060806138a48a828b01613791565b93505060a06138b58a828b016135d9565b92505060c06138c68a828b016135d9565b91505092959891949750929550565b600080604083850312156138ec576138eb6132f5565b5b60006138fa858286016134b0565b925050602061390b858286016134b0565b9150509250929050565b61391e81613740565b811461392957600080fd5b50565b60008135905061393b81613915565b92915050565b60008060408385031215613958576139576132f5565b5b6000613966858286016134b0565b92505060206139778582860161392c565b9150509250929050565b61398a81613740565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6139c181613990565b82525050565b6040820160008201516139dd6000850182613981565b5060208201516139f060208501826139b8565b50505050565b6000604082019050613a0b60008301846139c7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613a5857607f821691505b602082108103613a6b57613a6a613a11565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613acd602f836133c0565b9150613ad882613a71565b604082019050919050565b60006020820190508181036000830152613afc81613ac0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b3d826134c5565b9150613b48836134c5565b9250828201905080821115613b6057613b5f613b03565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613b9c601f836133c0565b9150613ba782613b66565b602082019050919050565b60006020820190508181036000830152613bcb81613b8f565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b6000613c2e6039836133c0565b9150613c3982613bd2565b604082019050919050565b60006020820190508181036000830152613c5d81613c21565b9050919050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000613c9a6015836133c0565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b6000613d2c6037836133c0565b9150613d3782613cd0565b604082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b6000613d6d826134c5565b9150613d78836134c5565b9250828203905081811115613d9057613d8f613b03565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613e216025836133c0565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613e8d601d836133c0565b9150613e9882613e57565b602082019050919050565b60006020820190508181036000830152613ebc81613e80565b9050919050565b6000608082019050613ed8600083018761361b565b613ee56020830186613716565b613ef2604083018561353b565b613eff606083018461353b565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b6000613f3e6019836133c0565b9150613f4982613f08565b602082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000613faa601d836133c0565b9150613fb582613f74565b602082019050919050565b60006020820190508181036000830152613fd981613f9d565b9050919050565b600060c082019050613ff5600083018961361b565b6140026020830188613716565b61400f6040830187613716565b61401c606083018661353b565b614029608083018561353b565b61403660a083018461353b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000614077601e836133c0565b915061408282614041565b602082019050919050565b600060208201905081810360008301526140a68161406a565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006141096024836133c0565b9150614114826140ad565b604082019050919050565b60006020820190508181036000830152614138816140fc565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061419b6022836133c0565b91506141a68261413f565b604082019050919050565b600060208201905081810360008301526141ca8161418e565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614207601d836133c0565b9150614212826141d1565b602082019050919050565b60006020820190508181036000830152614236816141fa565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006142996025836133c0565b91506142a48261423d565b604082019050919050565b600060208201905081810360008301526142c88161428c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061432b6023836133c0565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006143bd6026836133c0565b91506143c882614361565b604082019050919050565b600060208201905081810360008301526143ec816143b0565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b600061444f6026836133c0565b915061445a826143f3565b604082019050919050565b6000602082019050818103600083015261447e81614442565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006144c6601783614485565b91506144d182614490565b601782019050919050565b60006144e7826133b5565b6144f18185614485565b93506145018185602086016133d1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614543601183614485565b915061454e8261450d565b601182019050919050565b6000614564826144b9565b915061457082856144dc565b915061457b82614536565b915061458782846144dc565b91508190509392505050565b600060a0820190506145a8600083018861361b565b6145b5602083018761361b565b6145c2604083018661361b565b6145cf606083018561353b565b6145dc6080830184613716565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614620826134c5565b915061462b836134c5565b92508261463b5761463a6145e6565b5b828204905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061467c6014836133c0565b915061468782614646565b602082019050919050565b600060208201905081810360008301526146ab8161466f565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061470e6030836133c0565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b6000604082019050614759600083018561353b565b614766602083018461353b565b9392505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006147a36010836133c0565b91506147ae8261476d565b602082019050919050565b600060208201905081810360008301526147d281614796565b9050919050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061480f600283614485565b915061481a826147d9565b600282019050919050565b6000819050919050565b61484061483b826135b8565b614825565b82525050565b600061485182614802565b915061485d828561482f565b60208201915061486d828461482f565b6020820191508190509392505050565b6000608082019050614892600083018761361b565b61489f6020830186613692565b6148ac604083018561361b565b6148b9606083018461361b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006149276018836133c0565b9150614932826148f1565b602082019050919050565b600060208201905081810360008301526149568161491a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614993601f836133c0565b915061499e8261495d565b602082019050919050565b600060208201905081810360008301526149c281614986565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a256022836133c0565b9150614a30826149c9565b604082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ab76022836133c0565b9150614ac282614a5b565b604082019050919050565b60006020820190508181036000830152614ae681614aaa565b9050919050565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6000614b49602a836133c0565b9150614b5482614aed565b604082019050919050565b60006020820190508181036000830152614b7881614b3c565b9050919050565b6000614b8a826134c5565b9150614b95836134c5565b9250828202614ba3816134c5565b91508282048414831517614bba57614bb9613b03565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614bfb826134c5565b915060008203614c0e57614c0d613b03565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614c4f6020836133c0565b9150614c5a82614c19565b602082019050919050565b60006020820190508181036000830152614c7e81614c42565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b6000614cbb6019836133c0565b9150614cc682614c85565b602082019050919050565b60006020820190508181036000830152614cea81614cae565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d4d6021836133c0565b9150614d5882614cf1565b604082019050919050565b60006020820190508181036000830152614d7c81614d40565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ddf6022836133c0565b9150614dea82614d83565b604082019050919050565b60006020820190508181036000830152614e0e81614dd2565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614e4b601f836133c0565b9150614e5682614e15565b602082019050919050565b60006020820190508181036000830152614e7a81614e3e565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614edd6027836133c0565b9150614ee882614e81565b604082019050919050565b60006020820190508181036000830152614f0c81614ed0565b905091905056fea2646970667358221220fc046de338956e8aeca6864c04e8d3abc0bfe16b1e4bab5dd46bfa48e925c06564736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b578063a217fddf116100b8578063d53913931161007c578063d539139314610714578063d547741f14610732578063dd62ed3e1461074e578063e63ab1e91461077e578063f1127ed81461079c5761023d565b8063a217fddf1461065e578063a457c2d71461067c578063a9059cbb146106ac578063c3cda520146106dc578063d505accf146106f85761023d565b80638456cb59116100ff5780638456cb59146105a65780638e539e8c146105b057806391d14854146105e057806395d89b41146106105780639ab24eb01461062e5761023d565b80636fcfff45146104dc57806370a082311461050c57806375b238fc1461053c57806379cc67901461055a5780637ecebe00146105765761023d565b80633644e515116101c957806340c10f191161018d57806340c10f191461043a57806342966c6814610456578063587cde1e146104725780635c19a95c146104a25780635c975abb146104be5761023d565b80633644e5151461039657806336568abe146103b457806339509351146103d05780633a46b1a8146104005780633f4ba83a146104305761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a578063355274ea146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613352565b6107cc565b604051610269919061339a565b60405180910390f35b61027a610846565b6040516102879190613445565b60405180910390f35b6102aa60048036038101906102a591906134fb565b6108d8565b6040516102b7919061339a565b60405180910390f35b6102c86108fb565b6040516102d5919061354a565b60405180910390f35b6102f860048036038101906102f39190613565565b610905565b604051610305919061339a565b60405180910390f35b610328600480360381019061032391906135ee565b610934565b604051610335919061362a565b60405180910390f35b61035860048036038101906103539190613645565b610953565b005b610362610974565b60405161036f91906136a1565b60405180910390f35b61038061097d565b60405161038d919061354a565b60405180910390f35b61039e6109a5565b6040516103ab919061362a565b60405180910390f35b6103ce60048036038101906103c99190613645565b6109b4565b005b6103ea60048036038101906103e591906134fb565b610a37565b6040516103f7919061339a565b60405180910390f35b61041a600480360381019061041591906134fb565b610a6e565b604051610427919061354a565b60405180910390f35b610438610b02565b005b610454600480360381019061044f91906134fb565b610b7c565b005b610470600480360381019061046b91906136bc565b610bf3565b005b61048c600480360381019061048791906136e9565b610c07565b6040516104999190613725565b60405180910390f35b6104bc60048036038101906104b791906136e9565b610c70565b005b6104c6610c84565b6040516104d3919061339a565b60405180910390f35b6104f660048036038101906104f191906136e9565b610c9b565b604051610503919061375f565b60405180910390f35b610526600480360381019061052191906136e9565b610cef565b604051610533919061354a565b60405180910390f35b610544610d38565b604051610551919061362a565b60405180910390f35b610574600480360381019061056f91906134fb565b610d5c565b005b610590600480360381019061058b91906136e9565b610d7c565b60405161059d919061354a565b60405180910390f35b6105ae610dcc565b005b6105ca60048036038101906105c591906136bc565b610e46565b6040516105d7919061354a565b60405180910390f35b6105fa60048036038101906105f59190613645565b610e9c565b604051610607919061339a565b60405180910390f35b610618610f06565b6040516106259190613445565b60405180910390f35b610648600480360381019061064391906136e9565b610f98565b604051610655919061354a565b60405180910390f35b6106666110a9565b604051610673919061362a565b60405180910390f35b610696600480360381019061069191906134fb565b6110b0565b6040516106a3919061339a565b60405180910390f35b6106c660048036038101906106c191906134fb565b611127565b6040516106d3919061339a565b60405180910390f35b6106f660048036038101906106f191906137a6565b61114a565b005b610712600480360381019061070d9190613833565b61124e565b005b61071c611390565b604051610729919061362a565b60405180910390f35b61074c60048036038101906107479190613645565b6113b4565b005b610768600480360381019061076391906138d5565b6113d5565b604051610775919061354a565b60405180910390f35b61078661145c565b604051610793919061362a565b60405180910390f35b6107b660048036038101906107b19190613941565b611480565b6040516107c391906139f6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083f575061083e82611590565b5b9050919050565b60606004805461085590613a40565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613a40565b80156108ce5780601f106108a3576101008083540402835291602001916108ce565b820191906000526020600020905b8154815290600101906020018083116108b157829003601f168201915b5050505050905090565b6000806108e36115fa565b90506108f0818585611602565b600191505092915050565b6000600354905090565b6000806109106115fa565b905061091d8582856117cb565b610928858585611857565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61095c82610934565b61096581611ad9565b61096f8383611aed565b505050565b60006012905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60006109af611bcd565b905090565b6109bc6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2090613ae3565b60405180910390fd5b610a338282611ce7565b5050565b600080610a426115fa565b9050610a63818585610a5485896113d5565b610a5e9190613b32565b611602565b600191505092915050565b6000438210610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990613bb2565b60405180910390fd5b610afa600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083611dc8565b905092915050565b610b337f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b2e6115fa565b610e9c565b610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613c44565b60405180910390fd5b610b7a611ed4565b565b610ba67ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc933610e9c565b610be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdc90613cb0565b60405180910390fd5b610bef8282611f37565b5050565b610c04610bfe6115fa565b82611f45565b50565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6115fa565b82611f53565b50565b6000600660009054906101000a900460ff16905090565b6000610ce8600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061206d565b9050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b610d6e82610d686115fa565b836117cb565b610d788282611f45565b5050565b6000610dc5600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120c0565b9050919050565b610dfd7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610df86115fa565b610e9c565b610e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3390613d42565b60405180910390fd5b610e446120ce565b565b6000438210610e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8190613bb2565b60405180910390fd5b610e95600b83611dc8565b9050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060058054610f1590613a40565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4190613a40565b8015610f8e5780601f10610f6357610100808354040283529160200191610f8e565b820191906000526020600020905b815481529060010190602001808311610f7157829003601f168201915b5050505050905090565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461108057600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826110349190613d62565b8154811061104557611044613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611083565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110bb6115fa565b905060006110c982866113d5565b90508381101561110e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110590613e37565b60405180910390fd5b61111b8286868403611602565b60019250505092915050565b6000806111326115fa565b905061113f818585611857565b600191505092915050565b8342111561118d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118490613ea3565b60405180910390fd5b60006111ef6111e77fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111cc9493929190613ec3565b60405160208183030381529060405280519060200120612131565b85858561214b565b90506111fa81612176565b861461123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613f54565b60405180910390fd5b6112458188611f53565b50505050505050565b83421115611291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128890613fc0565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112c08c612176565b896040516020016112d696959493929190613fe0565b60405160208183030381529060405280519060200120905060006112f982612131565b905060006113098287878761214b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611379576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113709061408d565b60405180910390fd5b6113848a8a8a611602565b50505050505050505050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6113bd82610934565b6113c681611ad9565b6113d08383611ce7565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6114886132b7565b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106114df576114de613d96565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611671576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116689061411f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d7906141b1565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117be919061354a565b60405180910390a3505050565b60006117d784846113d5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118515781811015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183a9061421d565b60405180910390fd5b6118508484848403611602565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906142af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192c90614341565b60405180910390fd5b6119408383836121d4565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156119c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119be906143d3565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a5c9190613b32565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611ac0919061354a565b60405180910390a3611ad38484846121e4565b50505050565b611aea81611ae56115fa565b6121f4565b50565b611af78282610e9c565b611bc957600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611b6e6115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611c4957507f000000000000000000000000000000000000000000000000000000000000000046145b15611c76577f00000000000000000000000000000000000000000000000000000000000000009050611ce4565b611ce17f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612291565b90505b90565b611cf18282610e9c565b15611dc457600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611d696115fa565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b81811015611e47576000611de982846122cb565b905084868281548110611dff57611dfe613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff161115611e3157809250611e41565b600181611e3e9190613b32565b91505b50611dd5565b60008214611ea95784600183611e5d9190613d62565b81548110611e6e57611e6d613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611eac565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b611edc6122f1565b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611f206115fa565b604051611f2d9190613725565b60405180910390a1565b611f41828261233a565b5050565b611f4f82826123c7565b5050565b6000611f5e83610c07565b90506000611f6b84610cef565b905082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46120678284836123e5565b50505050565b600063ffffffff80168211156120b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120af90614465565b60405180910390fd5b819050919050565b600081600001549050919050565b6120d66125de565b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861211a6115fa565b6040516121279190613725565b60405180910390a1565b600061214461213e611bcd565b83612628565b9050919050565b600080600061215c8787878761265b565b9150915061216981612767565b8192505050949350505050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506121c3816120c0565b91506121ce81612933565b50919050565b6121df838383612949565b505050565b6121ef838383612949565b505050565b6121fe8282610e9c565b61228d576122238173ffffffffffffffffffffffffffffffffffffffff1660146129a1565b6122318360001c60206129a1565b604051602001612242929190614559565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122849190613445565b60405180910390fd5b5050565b600083838346306040516020016122ac959493929190614593565b6040516020818303038152906040528051906020012090509392505050565b600060028284186122dc9190614615565b8284166122e99190613b32565b905092915050565b6122f9610c84565b612338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232f90614692565b60405180910390fd5b565b6123448282612bdd565b61234c612c47565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123726108fb565b11156123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123aa90614724565b60405180910390fd5b6123c1600b612c6b83612c81565b50505050565b6123d18282612ef9565b6123df600b6130d183612c81565b50505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156124215750600081115b156125d957600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146124ff576000806124a8600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206130d185612c81565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516124f4929190614744565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146125d857600080612581600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c6b85612c81565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516125cd929190614744565b60405180910390a250505b5b505050565b6125e6610c84565b15612626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261d906147b9565b60405180910390fd5b565b6000828260405160200161263d929190614846565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561269657600060039150915061275e565b601b8560ff16141580156126ae5750601c8560ff1614155b156126c057600060049150915061275e565b6000600187878787604051600081526020016040526040516126e5949392919061487d565b6020604051602081039080840390855afa158015612707573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127555760006001925092505061275e565b80600092509250505b94509492505050565b6000600481111561277b5761277a6148c2565b5b81600481111561278e5761278d6148c2565b5b031561293057600160048111156127a8576127a76148c2565b5b8160048111156127bb576127ba6148c2565b5b036127fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f29061493d565b60405180910390fd5b6002600481111561280f5761280e6148c2565b5b816004811115612822576128216148c2565b5b03612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149a9565b60405180910390fd5b60036004811115612876576128756148c2565b5b816004811115612889576128886148c2565b5b036128c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c090614a3b565b60405180910390fd5b6004808111156128dc576128db6148c2565b5b8160048111156128ef576128ee6148c2565b5b0361292f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292690614acd565b60405180910390fd5b5b50565b6001816000016000828254019250508190555050565b6129548383836130e7565b61295c610c84565b1561299c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299390614b5f565b60405180910390fd5b505050565b6060600060028360026129b49190614b7f565b6129be9190613b32565b67ffffffffffffffff8111156129d7576129d6614bc1565b5b6040519080825280601f01601f191660200182016040528015612a095781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a4157612a40613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612aa557612aa4613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ae59190614b7f565b612aef9190613b32565b90505b6001811115612b8f577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b3157612b30613d96565b5b1a60f81b828281518110612b4857612b47613d96565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612b8890614bf0565b9050612af2565b5060008414612bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bca90614c65565b60405180910390fd5b8091505092915050565b612be561097d565b81612bee6108fb565b612bf89190613b32565b1115612c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3090614cd1565b60405180910390fd5b612c4382826130ec565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008183612c799190613b32565b905092915050565b60008060008580549050905060008114612cef5785600182612ca39190613d62565b81548110612cb457612cb3613d96565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612cf2565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612d2083858763ffffffff16565b9150600081118015612d7357504386600183612d3c9190613d62565b81548110612d4d57612d4c613d96565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612e0057612d818261324c565b86600183612d8f9190613d62565b81548110612da057612d9f613d96565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612ef0565b856040518060400160405280612e154361206d565b63ffffffff168152602001612e298561324c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5f90614d63565b60405180910390fd5b612f74826000836121d4565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff290614df5565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600360008282546130539190613d62565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130b8919061354a565b60405180910390a36130cc836000846121e4565b505050565b600081836130df9190613d62565b905092915050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361315b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315290614e61565b60405180910390fd5b613167600083836121d4565b80600360008282546131799190613b32565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131cf9190613b32565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613234919061354a565b60405180910390a3613248600083836121e4565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156132af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132a690614ef3565b60405180910390fd5b819050919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61332f816132fa565b811461333a57600080fd5b50565b60008135905061334c81613326565b92915050565b600060208284031215613368576133676132f5565b5b60006133768482850161333d565b91505092915050565b60008115159050919050565b6133948161337f565b82525050565b60006020820190506133af600083018461338b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156133ef5780820151818401526020810190506133d4565b60008484015250505050565b6000601f19601f8301169050919050565b6000613417826133b5565b61342181856133c0565b93506134318185602086016133d1565b61343a816133fb565b840191505092915050565b6000602082019050818103600083015261345f818461340c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061349282613467565b9050919050565b6134a281613487565b81146134ad57600080fd5b50565b6000813590506134bf81613499565b92915050565b6000819050919050565b6134d8816134c5565b81146134e357600080fd5b50565b6000813590506134f5816134cf565b92915050565b60008060408385031215613512576135116132f5565b5b6000613520858286016134b0565b9250506020613531858286016134e6565b9150509250929050565b613544816134c5565b82525050565b600060208201905061355f600083018461353b565b92915050565b60008060006060848603121561357e5761357d6132f5565b5b600061358c868287016134b0565b935050602061359d868287016134b0565b92505060406135ae868287016134e6565b9150509250925092565b6000819050919050565b6135cb816135b8565b81146135d657600080fd5b50565b6000813590506135e8816135c2565b92915050565b600060208284031215613604576136036132f5565b5b6000613612848285016135d9565b91505092915050565b613624816135b8565b82525050565b600060208201905061363f600083018461361b565b92915050565b6000806040838503121561365c5761365b6132f5565b5b600061366a858286016135d9565b925050602061367b858286016134b0565b9150509250929050565b600060ff82169050919050565b61369b81613685565b82525050565b60006020820190506136b66000830184613692565b92915050565b6000602082840312156136d2576136d16132f5565b5b60006136e0848285016134e6565b91505092915050565b6000602082840312156136ff576136fe6132f5565b5b600061370d848285016134b0565b91505092915050565b61371f81613487565b82525050565b600060208201905061373a6000830184613716565b92915050565b600063ffffffff82169050919050565b61375981613740565b82525050565b60006020820190506137746000830184613750565b92915050565b61378381613685565b811461378e57600080fd5b50565b6000813590506137a08161377a565b92915050565b60008060008060008060c087890312156137c3576137c26132f5565b5b60006137d189828a016134b0565b96505060206137e289828a016134e6565b95505060406137f389828a016134e6565b945050606061380489828a01613791565b935050608061381589828a016135d9565b92505060a061382689828a016135d9565b9150509295509295509295565b600080600080600080600060e0888a031215613852576138516132f5565b5b60006138608a828b016134b0565b97505060206138718a828b016134b0565b96505060406138828a828b016134e6565b95505060606138938a828b016134e6565b94505060806138a48a828b01613791565b93505060a06138b58a828b016135d9565b92505060c06138c68a828b016135d9565b91505092959891949750929550565b600080604083850312156138ec576138eb6132f5565b5b60006138fa858286016134b0565b925050602061390b858286016134b0565b9150509250929050565b61391e81613740565b811461392957600080fd5b50565b60008135905061393b81613915565b92915050565b60008060408385031215613958576139576132f5565b5b6000613966858286016134b0565b92505060206139778582860161392c565b9150509250929050565b61398a81613740565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6139c181613990565b82525050565b6040820160008201516139dd6000850182613981565b5060208201516139f060208501826139b8565b50505050565b6000604082019050613a0b60008301846139c7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613a5857607f821691505b602082108103613a6b57613a6a613a11565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613acd602f836133c0565b9150613ad882613a71565b604082019050919050565b60006020820190508181036000830152613afc81613ac0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b3d826134c5565b9150613b48836134c5565b9250828201905080821115613b6057613b5f613b03565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613b9c601f836133c0565b9150613ba782613b66565b602082019050919050565b60006020820190508181036000830152613bcb81613b8f565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b6000613c2e6039836133c0565b9150613c3982613bd2565b604082019050919050565b60006020820190508181036000830152613c5d81613c21565b9050919050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000613c9a6015836133c0565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b6000613d2c6037836133c0565b9150613d3782613cd0565b604082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b6000613d6d826134c5565b9150613d78836134c5565b9250828203905081811115613d9057613d8f613b03565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613e216025836133c0565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613e8d601d836133c0565b9150613e9882613e57565b602082019050919050565b60006020820190508181036000830152613ebc81613e80565b9050919050565b6000608082019050613ed8600083018761361b565b613ee56020830186613716565b613ef2604083018561353b565b613eff606083018461353b565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b6000613f3e6019836133c0565b9150613f4982613f08565b602082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000613faa601d836133c0565b9150613fb582613f74565b602082019050919050565b60006020820190508181036000830152613fd981613f9d565b9050919050565b600060c082019050613ff5600083018961361b565b6140026020830188613716565b61400f6040830187613716565b61401c606083018661353b565b614029608083018561353b565b61403660a083018461353b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000614077601e836133c0565b915061408282614041565b602082019050919050565b600060208201905081810360008301526140a68161406a565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006141096024836133c0565b9150614114826140ad565b604082019050919050565b60006020820190508181036000830152614138816140fc565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061419b6022836133c0565b91506141a68261413f565b604082019050919050565b600060208201905081810360008301526141ca8161418e565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614207601d836133c0565b9150614212826141d1565b602082019050919050565b60006020820190508181036000830152614236816141fa565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006142996025836133c0565b91506142a48261423d565b604082019050919050565b600060208201905081810360008301526142c88161428c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061432b6023836133c0565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006143bd6026836133c0565b91506143c882614361565b604082019050919050565b600060208201905081810360008301526143ec816143b0565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b600061444f6026836133c0565b915061445a826143f3565b604082019050919050565b6000602082019050818103600083015261447e81614442565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006144c6601783614485565b91506144d182614490565b601782019050919050565b60006144e7826133b5565b6144f18185614485565b93506145018185602086016133d1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614543601183614485565b915061454e8261450d565b601182019050919050565b6000614564826144b9565b915061457082856144dc565b915061457b82614536565b915061458782846144dc565b91508190509392505050565b600060a0820190506145a8600083018861361b565b6145b5602083018761361b565b6145c2604083018661361b565b6145cf606083018561353b565b6145dc6080830184613716565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614620826134c5565b915061462b836134c5565b92508261463b5761463a6145e6565b5b828204905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061467c6014836133c0565b915061468782614646565b602082019050919050565b600060208201905081810360008301526146ab8161466f565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061470e6030836133c0565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b6000604082019050614759600083018561353b565b614766602083018461353b565b9392505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006147a36010836133c0565b91506147ae8261476d565b602082019050919050565b600060208201905081810360008301526147d281614796565b9050919050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061480f600283614485565b915061481a826147d9565b600282019050919050565b6000819050919050565b61484061483b826135b8565b614825565b82525050565b600061485182614802565b915061485d828561482f565b60208201915061486d828461482f565b6020820191508190509392505050565b6000608082019050614892600083018761361b565b61489f6020830186613692565b6148ac604083018561361b565b6148b9606083018461361b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006149276018836133c0565b9150614932826148f1565b602082019050919050565b600060208201905081810360008301526149568161491a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614993601f836133c0565b915061499e8261495d565b602082019050919050565b600060208201905081810360008301526149c281614986565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a256022836133c0565b9150614a30826149c9565b604082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ab76022836133c0565b9150614ac282614a5b565b604082019050919050565b60006020820190508181036000830152614ae681614aaa565b9050919050565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6000614b49602a836133c0565b9150614b5482614aed565b604082019050919050565b60006020820190508181036000830152614b7881614b3c565b9050919050565b6000614b8a826134c5565b9150614b95836134c5565b9250828202614ba3816134c5565b91508282048414831517614bba57614bb9613b03565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614bfb826134c5565b915060008203614c0e57614c0d613b03565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614c4f6020836133c0565b9150614c5a82614c19565b602082019050919050565b60006020820190508181036000830152614c7e81614c42565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b6000614cbb6019836133c0565b9150614cc682614c85565b602082019050919050565b60006020820190508181036000830152614cea81614cae565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d4d6021836133c0565b9150614d5882614cf1565b604082019050919050565b60006020820190508181036000830152614d7c81614d40565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ddf6022836133c0565b9150614dea82614d83565b604082019050919050565b60006020820190508181036000830152614e0e81614dd2565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614e4b601f836133c0565b9150614e5682614e15565b602082019050919050565b60006020820190508181036000830152614e7a81614e3e565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614edd6027836133c0565b9150614ee882614e81565b604082019050919050565b60006020820190508181036000830152614f0c81614ed0565b905091905056fea2646970667358221220fc046de338956e8aeca6864c04e8d3abc0bfe16b1e4bab5dd46bfa48e925c06564736f6c63430008110033","abi":[{"inputs":[{"internalType":"uint256","name":"cap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ADMIN_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":"DOMAIN_SEPARATOR","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":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/Multisender.json b/deployments/mumbai_80001/Multisender.json deleted file mode 100644 index bce00d4..0000000 --- a/deployments/mumbai_80001/Multisender.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Multisender.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// This contract does one thing, simply. it allows you to send eth or tokens to multiple recipients. Useful for setting up a testnet and funding all the validators and stakers.\\n\\ncontract Multisender is Ownable {\\n function sendEth(address[] calldata _recipients) public payable {\\n uint256 val = msg.value / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n payable(_recipients[i]).transfer(val);\\n }\\n }\\n\\n function sendTokens(address[] calldata _recipients, address tokenContract)\\n public\\n {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n uint256 val = bal / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n tkn.transfer(_recipients[i], val);\\n }\\n }\\n\\n function withdraw() public onlyOwner {\\n payable(msg.sender).transfer(address(this).balance);\\n }\\n\\n function withdrawTokens(address tokenContract) public onlyOwner {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n tkn.transfer(msg.sender, bal);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x244728F20d5bBcEac394423DC1dd21Ef4E27b582","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610bf98061010d6000396000f3fe6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","abi":[{"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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"sendEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"address","name":"tokenContract","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/PKPHelper.json b/deployments/mumbai_80001/PKPHelper.json deleted file mode 100644 index 543003d..0000000 --- a/deployments/mumbai_80001/PKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = PKPNFT(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNextAndAddAuthMethods(\\n uint256 keyType,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintNextAndAddAuthMethodsWithTypes(\\n keyType,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintNextAndAddAuthMethodsWithTypes(\\n uint256 keyType,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mintNext{ value: msg.value }(keyType);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpPermissions.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(address newPkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address, /* operator */\\n address, /* from */\\n uint256, /* tokenId */\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10**stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10**stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(address stakerAddress)\\n public\\n view\\n returns (bool)\\n {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.epochlength\\n require(\\n block.number >= epoch.endBlock + epoch.epochLength,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n epoch.endBlock = block.number + epoch.epochLength;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10**stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress);\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(uint256 newKickPenaltyPercent)\\n public\\n onlyOwner\\n {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(address newResolverContractAddress)\\n public\\n onlyOwner\\n {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(address indexed staker);\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n PubkeyRouter public router;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _router) {\\n pkpNFT = PKPNFT(_pkpNft);\\n router = PubkeyRouter(_router);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(uint256 authMethodType, bytes memory id)\\n public\\n pure\\n returns (uint256)\\n {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(uint256 authMethodType, bytes calldata id)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(uint256 tokenId)\\n external\\n view\\n returns (AuthMethod[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(uint256 tokenId)\\n public\\n view\\n returns (bytes[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(uint256 tokenId)\\n public\\n view\\n returns (address[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(uint256 tokenId, address user)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n function setRouterAddress(address newRouterAddress) public onlyOwner {\\n router = PubkeyRouter(newRouterAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x62F0674589557c21411968CadC6F8c997cC1F83A","bytecode":"0x60806040523480156200001157600080fd5b50604051620024f3380380620024f3833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b612285806200026e6000396000f3fe6080604052600436106100915760003560e01c80638da5cb5b116100595780638da5cb5b1461016c57806397016f3f146101975780639fba176b146101c2578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc5780631f71cb3114610125578063715018a614610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117c0565b60405180910390f35b34801561016157600080fd5b5061016a610b59565b005b34801561017857600080fd5b50610181610b6d565b60405161018e91906117ea565b60405180910390f35b3480156101a357600080fd5b506101ac610b96565b6040516101b99190611864565b60405180910390f35b6101dc60048036038101906101d7919061187f565b610bbc565b6040516101e991906117c0565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119b2565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a50565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d228b16348f6040518363ffffffff1660e01b81526004016103e291906117c0565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611a85565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611b24565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611bb6565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611c48565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611cda565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611d6c565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611d8c565b5b60200260200101518f85815181106105fd576105fc611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611ef8565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611f6c565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611d8c565b5b60200260200101518d85815181106106ec576106eb611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161071293929190611fb4565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611f6c565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611d8c565b5b602002602001015181526020018c86815181106107eb576107ea611d8c565b5b602002602001015181526020018b868151811061080b5761080a611d8c565b5b602002602001015181525089858151811061082957610828611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161084f93929190612093565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611f6c565b915050610765565b505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117c0565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093491906120ed565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff8111156109975761099661112d565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e493929190611fb4565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c9392919061211a565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b129392919061211a565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b610b61610dba565b610b6b6000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610d0488600067ffffffffffffffff811115610bdd57610bdc61112d565b5b604051908082528060200260200182016040528015610c1057816020015b6060815260200190600190039081610bfb5790505b50600067ffffffffffffffff811115610c2c57610c2b61112d565b5b604051908082528060200260200182016040528015610c5f57816020015b6060815260200190600190039081610c4a5790505b50600067ffffffffffffffff811115610c7b57610c7a61112d565b5b604051908082528060200260200182016040528015610ca95781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610cc557610cc461112d565b5b604051908082528060200260200182016040528015610cf857816020015b6060815260200190600190039081610ce35790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f906121c3565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610b6d565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d9061222f565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111658261111c565b810181811067ffffffffffffffff821117156111845761118361112d565b5b80604052505050565b6000611197610f04565b90506111a3828261115c565b919050565b600067ffffffffffffffff8211156111c3576111c261112d565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff8211156111f4576111f361112d565b5b6111fd8261111c565b9050602081019050919050565b82818337600083830152505050565b600061122c611227846111d9565b61118d565b905082815260208101848484011115611248576112476111d4565b5b61125384828561120a565b509392505050565b600082601f8301126112705761126f610fac565b5b8135611280848260208601611219565b91505092915050565b600061129c611297846111a8565b61118d565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261125b565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff8211156113595761135861112d565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156113855761138461112d565b5b602082029050602081019050919050565b60006113a96113a48461136a565b61118d565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b61118d565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc61112d565b5b602082029050602081019050919050565b600061152161151c846114e2565b61118d565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60006116118e828f01610f97565b9b505060208c013567ffffffffffffffff81111561163257611631610f13565b5b61163e8e828f01611310565b9a505060408c013567ffffffffffffffff81111561165f5761165e610f13565b5b61166b8e828f016114b4565b99505060608c013567ffffffffffffffff81111561168c5761168b610f13565b5b6116988e828f01611577565b98505060808c013567ffffffffffffffff8111156116b9576116b8610f13565b5b6116c58e828f016114b4565b97505060a08c013567ffffffffffffffff8111156116e6576116e5610f13565b5b6116f28e828f016113ff565b96505060c08c013567ffffffffffffffff81111561171357611712610f13565b5b61171f8e828f01611310565b95505060e08c013567ffffffffffffffff8111156117405761173f610f13565b5b61174c8e828f01611310565b9450506101008c013567ffffffffffffffff81111561176e5761176d610f13565b5b61177a8e828f016114b4565b93505061012061178c8e828f016115c8565b92505061014061179e8e828f016115c8565b9150509295989b509295989b9093969950565b6117ba81610f76565b82525050565b60006020820190506117d560008301846117b1565b92915050565b6117e481610f38565b82525050565b60006020820190506117ff60008301846117db565b92915050565b6000819050919050565b600061182a61182561182084610f18565b611805565b610f18565b9050919050565b600061183c8261180f565b9050919050565b600061184e82611831565b9050919050565b61185e81611843565b82525050565b60006020820190506118796000830184611855565b92915050565b600080600080600080600060e0888a03121561189e5761189d610f0e565b5b60006118ac8a828b01610f97565b975050602088013567ffffffffffffffff8111156118cd576118cc610f13565b5b6118d98a828b016113ff565b965050604088013567ffffffffffffffff8111156118fa576118f9610f13565b5b6119068a828b01611310565b955050606088013567ffffffffffffffff81111561192757611926610f13565b5b6119338a828b01611310565b945050608088013567ffffffffffffffff81111561195457611953610f13565b5b6119608a828b016114b4565b93505060a06119718a828b016115c8565b92505060c06119828a828b016115c8565b91505092959891949750929550565b600061199c82611831565b9050919050565b6119ac81611991565b82525050565b60006020820190506119c760008301846119a3565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a3a603a836119cd565b9150611a45826119de565b604082019050919050565b60006020820190508181036000830152611a6981611a2d565b9050919050565b600081519050611a7f81610f80565b92915050565b600060208284031215611a9b57611a9a610f0e565b5b6000611aa984828501611a70565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611b0e6036836119cd565b9150611b1982611ab2565b604082019050919050565b60006020820190508181036000830152611b3d81611b01565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611ba06035836119cd565b9150611bab82611b44565b604082019050919050565b60006020820190508181036000830152611bcf81611b93565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611c32603b836119cd565b9150611c3d82611bd6565b604082019050919050565b60006020820190508181036000830152611c6181611c25565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611cc4603f836119cd565b9150611ccf82611c68565b604082019050919050565b60006020820190508181036000830152611cf381611cb7565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d56603f836119cd565b9150611d6182611cfa565b604082019050919050565b60006020820190508181036000830152611d8581611d49565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60005b83811015611df5578082015181840152602081019050611dda565b60008484015250505050565b6000611e0c82611dbb565b611e168185611dc6565b9350611e26818560208601611dd7565b611e2f8161111c565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611e6f81610f76565b82525050565b6000611e818383611e66565b60208301905092915050565b6000602082019050919050565b6000611ea582611e3a565b611eaf8185611e45565b9350611eba83611e56565b8060005b83811015611eeb578151611ed28882611e75565b9750611edd83611e8d565b925050600181019050611ebe565b5085935050505092915050565b6000606082019050611f0d60008301866117b1565b8181036020830152611f1f8185611e01565b90508181036040830152611f338184611e9a565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f7782610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fa957611fa8611f3d565b5b600182019050919050565b6000606082019050611fc960008301866117b1565b611fd660208301856117db565b8181036040830152611fe88184611e9a565b9050949350505050565b600082825260208201905092915050565b600061200e82611dbb565b6120188185611ff2565b9350612028818560208601611dd7565b6120318161111c565b840191505092915050565b60006060830160008301516120546000860182611e66565b506020830151848203602086015261206c8282612003565b915050604083015184820360408601526120868282612003565b9150508091505092915050565b60006060820190506120a860008301866117b1565b81810360208301526120ba818561203c565b905081810360408301526120ce8184611e9a565b9050949350505050565b6000815190506120e781610f4a565b92915050565b60006020828403121561210357612102610f0e565b5b6000612111848285016120d8565b91505092915050565b600060608201905061212f60008301866117db565b61213c60208301856117db565b61214960408301846117b1565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006121ad6026836119cd565b91506121b882612151565b604082019050919050565b600060208201905081810360008301526121dc816121a0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122196020836119cd565b9150612224826121e3565b602082019050919050565b600060208201905081810360008301526122488161220c565b905091905056fea26469706673582212206f1573ff29de905ff376f3741d47b297b0eefb11eecc52311f8791dda52558dc64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c80638da5cb5b116100595780638da5cb5b1461016c57806397016f3f146101975780639fba176b146101c2578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc5780631f71cb3114610125578063715018a614610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117c0565b60405180910390f35b34801561016157600080fd5b5061016a610b59565b005b34801561017857600080fd5b50610181610b6d565b60405161018e91906117ea565b60405180910390f35b3480156101a357600080fd5b506101ac610b96565b6040516101b99190611864565b60405180910390f35b6101dc60048036038101906101d7919061187f565b610bbc565b6040516101e991906117c0565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119b2565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a50565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d228b16348f6040518363ffffffff1660e01b81526004016103e291906117c0565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611a85565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611b24565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611bb6565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611c48565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611cda565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611d6c565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611d8c565b5b60200260200101518f85815181106105fd576105fc611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611ef8565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611f6c565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611d8c565b5b60200260200101518d85815181106106ec576106eb611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161071293929190611fb4565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611f6c565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611d8c565b5b602002602001015181526020018c86815181106107eb576107ea611d8c565b5b602002602001015181526020018b868151811061080b5761080a611d8c565b5b602002602001015181525089858151811061082957610828611d8c565b5b60200260200101516040518463ffffffff1660e01b815260040161084f93929190612093565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611f6c565b915050610765565b505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117c0565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093491906120ed565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff8111156109975761099661112d565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e493929190611fb4565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c9392919061211a565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b129392919061211a565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b610b61610dba565b610b6b6000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610d0488600067ffffffffffffffff811115610bdd57610bdc61112d565b5b604051908082528060200260200182016040528015610c1057816020015b6060815260200190600190039081610bfb5790505b50600067ffffffffffffffff811115610c2c57610c2b61112d565b5b604051908082528060200260200182016040528015610c5f57816020015b6060815260200190600190039081610c4a5790505b50600067ffffffffffffffff811115610c7b57610c7a61112d565b5b604051908082528060200260200182016040528015610ca95781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610cc557610cc461112d565b5b604051908082528060200260200182016040528015610cf857816020015b6060815260200190600190039081610ce35790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f906121c3565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610b6d565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d9061222f565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6111658261111c565b810181811067ffffffffffffffff821117156111845761118361112d565b5b80604052505050565b6000611197610f04565b90506111a3828261115c565b919050565b600067ffffffffffffffff8211156111c3576111c261112d565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff8211156111f4576111f361112d565b5b6111fd8261111c565b9050602081019050919050565b82818337600083830152505050565b600061122c611227846111d9565b61118d565b905082815260208101848484011115611248576112476111d4565b5b61125384828561120a565b509392505050565b600082601f8301126112705761126f610fac565b5b8135611280848260208601611219565b91505092915050565b600061129c611297846111a8565b61118d565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261125b565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff8211156113595761135861112d565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156113855761138461112d565b5b602082029050602081019050919050565b60006113a96113a48461136a565b61118d565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b61118d565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc61112d565b5b602082029050602081019050919050565b600061152161151c846114e2565b61118d565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60006116118e828f01610f97565b9b505060208c013567ffffffffffffffff81111561163257611631610f13565b5b61163e8e828f01611310565b9a505060408c013567ffffffffffffffff81111561165f5761165e610f13565b5b61166b8e828f016114b4565b99505060608c013567ffffffffffffffff81111561168c5761168b610f13565b5b6116988e828f01611577565b98505060808c013567ffffffffffffffff8111156116b9576116b8610f13565b5b6116c58e828f016114b4565b97505060a08c013567ffffffffffffffff8111156116e6576116e5610f13565b5b6116f28e828f016113ff565b96505060c08c013567ffffffffffffffff81111561171357611712610f13565b5b61171f8e828f01611310565b95505060e08c013567ffffffffffffffff8111156117405761173f610f13565b5b61174c8e828f01611310565b9450506101008c013567ffffffffffffffff81111561176e5761176d610f13565b5b61177a8e828f016114b4565b93505061012061178c8e828f016115c8565b92505061014061179e8e828f016115c8565b9150509295989b509295989b9093969950565b6117ba81610f76565b82525050565b60006020820190506117d560008301846117b1565b92915050565b6117e481610f38565b82525050565b60006020820190506117ff60008301846117db565b92915050565b6000819050919050565b600061182a61182561182084610f18565b611805565b610f18565b9050919050565b600061183c8261180f565b9050919050565b600061184e82611831565b9050919050565b61185e81611843565b82525050565b60006020820190506118796000830184611855565b92915050565b600080600080600080600060e0888a03121561189e5761189d610f0e565b5b60006118ac8a828b01610f97565b975050602088013567ffffffffffffffff8111156118cd576118cc610f13565b5b6118d98a828b016113ff565b965050604088013567ffffffffffffffff8111156118fa576118f9610f13565b5b6119068a828b01611310565b955050606088013567ffffffffffffffff81111561192757611926610f13565b5b6119338a828b01611310565b945050608088013567ffffffffffffffff81111561195457611953610f13565b5b6119608a828b016114b4565b93505060a06119718a828b016115c8565b92505060c06119828a828b016115c8565b91505092959891949750929550565b600061199c82611831565b9050919050565b6119ac81611991565b82525050565b60006020820190506119c760008301846119a3565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a3a603a836119cd565b9150611a45826119de565b604082019050919050565b60006020820190508181036000830152611a6981611a2d565b9050919050565b600081519050611a7f81610f80565b92915050565b600060208284031215611a9b57611a9a610f0e565b5b6000611aa984828501611a70565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611b0e6036836119cd565b9150611b1982611ab2565b604082019050919050565b60006020820190508181036000830152611b3d81611b01565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611ba06035836119cd565b9150611bab82611b44565b604082019050919050565b60006020820190508181036000830152611bcf81611b93565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611c32603b836119cd565b9150611c3d82611bd6565b604082019050919050565b60006020820190508181036000830152611c6181611c25565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611cc4603f836119cd565b9150611ccf82611c68565b604082019050919050565b60006020820190508181036000830152611cf381611cb7565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d56603f836119cd565b9150611d6182611cfa565b604082019050919050565b60006020820190508181036000830152611d8581611d49565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60005b83811015611df5578082015181840152602081019050611dda565b60008484015250505050565b6000611e0c82611dbb565b611e168185611dc6565b9350611e26818560208601611dd7565b611e2f8161111c565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611e6f81610f76565b82525050565b6000611e818383611e66565b60208301905092915050565b6000602082019050919050565b6000611ea582611e3a565b611eaf8185611e45565b9350611eba83611e56565b8060005b83811015611eeb578151611ed28882611e75565b9750611edd83611e8d565b925050600181019050611ebe565b5085935050505092915050565b6000606082019050611f0d60008301866117b1565b8181036020830152611f1f8185611e01565b90508181036040830152611f338184611e9a565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f7782610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fa957611fa8611f3d565b5b600182019050919050565b6000606082019050611fc960008301866117b1565b611fd660208301856117db565b8181036040830152611fe88184611e9a565b9050949350505050565b600082825260208201905092915050565b600061200e82611dbb565b6120188185611ff2565b9350612028818560208601611dd7565b6120318161111c565b840191505092915050565b60006060830160008301516120546000860182611e66565b506020830151848203602086015261206c8282612003565b915050604083015184820360408601526120868282612003565b9150508091505092915050565b60006060820190506120a860008301866117b1565b81810360208301526120ba818561203c565b905081810360408301526120ce8184611e9a565b9050949350505050565b6000815190506120e781610f4a565b92915050565b60006020828403121561210357612102610f0e565b5b6000612111848285016120d8565b91505092915050565b600060608201905061212f60008301866117db565b61213c60208301856117db565b61214960408301846117b1565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006121ad6026836119cd565b91506121b882612151565b604082019050919050565b600060208201905081810360008301526121dc816121a0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122196020836119cd565b9150612224826121e3565b602082019050919050565b600060208201905081810360008301526122488161220c565b905091905056fea26469706673582212206f1573ff29de905ff376f3741d47b297b0eefb11eecc52311f8791dda52558dc64736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintNextAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintNextAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/PKPNFT.json b/deployments/mumbai_80001/PKPNFT.json deleted file mode 100644 index fb75731..0000000 --- a/deployments/mumbai_80001/PKPNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10**stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10**stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(address stakerAddress)\\n public\\n view\\n returns (bool)\\n {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.epochlength\\n require(\\n block.number >= epoch.endBlock + epoch.epochLength,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n epoch.endBlock = block.number + epoch.epochLength;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10**stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress);\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(uint256 newKickPenaltyPercent)\\n public\\n onlyOwner\\n {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(address newResolverContractAddress)\\n public\\n onlyOwner\\n {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(address indexed staker);\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n PubkeyRouter public router;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _router) {\\n pkpNFT = PKPNFT(_pkpNft);\\n router = PubkeyRouter(_router);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(uint256 authMethodType, bytes memory id)\\n public\\n pure\\n returns (uint256)\\n {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(uint256 authMethodType, bytes calldata id)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(uint256 tokenId)\\n external\\n view\\n returns (AuthMethod[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(uint256 tokenId)\\n public\\n view\\n returns (bytes[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(uint256 tokenId)\\n public\\n view\\n returns (address[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(uint256 tokenId, address user)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n function setRouterAddress(address newRouterAddress) public onlyOwner {\\n router = PubkeyRouter(newRouterAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xBDCBd9eb8211C28985c1929A923D83f74a42f6db","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000468565b508060019081620000a1919062000468565b505050620000c4620000b86200012060201b60201c565b6200012860201b60201c565b6001600b81905550655af3107a4000600f8190555033601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200054f565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200027057607f821691505b60208210810362000286576200028562000228565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002f07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002b1565b620002fc8683620002b1565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000349620003436200033d8462000314565b6200031e565b62000314565b9050919050565b6000819050919050565b620003658362000328565b6200037d620003748262000350565b848454620002be565b825550505050565b600090565b6200039462000385565b620003a18184846200035a565b505050565b5b81811015620003c957620003bd6000826200038a565b600181019050620003a7565b5050565b601f8211156200041857620003e2816200028c565b620003ed84620002a1565b81016020851015620003fd578190505b620004156200040c85620002a1565b830182620003a6565b50505b505050565b600082821c905092915050565b60006200043d600019846008026200041d565b1980831691505092915050565b60006200045883836200042a565b9150826002028217905092915050565b6200047382620001ee565b67ffffffffffffffff8111156200048f576200048e620001f9565b5b6200049b825462000257565b620004a8828285620003cd565b600060209050601f831160018114620004e05760008415620004cb578287015190505b620004d785826200044a565b86555062000547565b601f198416620004f0866200028c565b60005b828110156200051a57848901518255600182019150602085019450602081019050620004f3565b868310156200053a578489015162000536601f8916826200042a565b8355505b6001600288020188555050505b505050505050565b6155b1806200055f6000396000f3fe60806040526004361061027d5760003560e01c80636352211e1161014f578063b94a2102116100c1578063e985e9c51161007a578063e985e9c5146109fc578063ef6fd87814610a39578063f2fde38b14610a76578063f556aeb114610a9f578063f70e72ef14610ac8578063f887ea4014610b055761027d565b8063b94a2102146108c6578063bd4986a0146108f1578063bdb4b8481461092e578063c87b56dd14610959578063d343682614610996578063d7b0398b146109bf5761027d565b80638da5cb5b116101135780638da5cb5b146107c85780639388f12e146107f357806395d89b411461081e57806397016f3f14610849578063a22cb46514610874578063b88d4fde1461089d5761027d565b80636352211e146106de57806366a306d71461071b57806370a082311461074b578063715018a6146107885780638545f4ea1461079f5761027d565b80633ccfd60b116101f35780634f558e79116101ac5780634f558e79146105a55780634f6ccce7146105e257806356e3a1ae1461061f5780635c110a9c1461065c5780635d228b16146106855780635f49663c146106b55761027d565b80633ccfd60b146104ad57806341cb87fc146104c457806342842e0e146104ed57806342966c681461051657806342dd8fcb1461053f5780634c19eae61461057c5761027d565b806318160ddd1161024557806318160ddd1461038d5780631ea89a22146103b85780631f275713146103e157806323b872dd1461041e5780632f745c59146104475780633b189852146104845761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b3146103275780631582391c14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613870565b610b30565b6040516102b691906138b8565b60405180910390f35b3480156102cb57600080fd5b506102d4610c6a565b6040516102e19190613963565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c91906139bb565b610cfc565b60405161031e9190613a29565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613a70565b610d42565b005b34801561035c57600080fd5b5061037760048036038101906103729190613b1f565b610e59565b6040516103849190613bbb565b60405180910390f35b34801561039957600080fd5b506103a2610e83565b6040516103af9190613bbb565b60405180910390f35b3480156103c457600080fd5b506103df60048036038101906103da9190613bd6565b610e90565b005b3480156103ed57600080fd5b5061040860048036038101906104039190613c03565b610f1f565b6040516104159190613c3f565b60405180910390f35b34801561042a57600080fd5b5061044560048036038101906104409190613c5a565b610f4f565b005b34801561045357600080fd5b5061046e60048036038101906104699190613a70565b610faf565b60405161047b9190613bbb565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190613bd6565b611054565b005b3480156104b957600080fd5b506104c26110e3565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b6111f6565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613c5a565b611285565b005b34801561052257600080fd5b5061053d600480360381019061053891906139bb565b6112a5565b005b34801561054b57600080fd5b50610566600480360381019061056191906139bb565b611301565b6040516105739190613bbb565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e9190613cad565b611321565b005b3480156105b157600080fd5b506105cc60048036038101906105c791906139bb565b6114eb565b6040516105d991906138b8565b60405180910390f35b3480156105ee57600080fd5b50610609600480360381019061060491906139bb565b6114fd565b6040516106169190613bbb565b60405180910390f35b34801561062b57600080fd5b50610646600480360381019061064191906139bb565b61156e565b60405161065391906138b8565b60405180910390f35b34801561066857600080fd5b50610683600480360381019061067e9190613d28565b61158e565b005b61069f600480360381019061069a91906139bb565b61168a565b6040516106ac9190613bbb565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d79190613bd6565b6116f0565b005b3480156106ea57600080fd5b50610705600480360381019061070091906139bb565b61177f565b6040516107129190613a29565b60405180910390f35b61073560048036038101906107309190613e9d565b611830565b6040516107429190613bbb565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613bd6565b61197a565b60405161077f9190613bbb565b60405180910390f35b34801561079457600080fd5b5061079d611a31565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906139bb565b611a45565b005b3480156107d457600080fd5b506107dd611a8e565b6040516107ea9190613a29565b60405180910390f35b3480156107ff57600080fd5b50610808611ab8565b6040516108159190613f58565b60405180910390f35b34801561082a57600080fd5b50610833611ade565b6040516108409190613963565b60405180910390f35b34801561085557600080fd5b5061085e611b70565b60405161086b9190613f94565b60405180910390f35b34801561088057600080fd5b5061089b60048036038101906108969190613fdb565b611b96565b005b3480156108a957600080fd5b506108c460048036038101906108bf919061401b565b611bac565b005b3480156108d257600080fd5b506108db611c0e565b6040516108e89190613a29565b60405180910390f35b3480156108fd57600080fd5b50610918600480360381019061091391906139bb565b611c34565b6040516109259190613a29565b60405180910390f35b34801561093a57600080fd5b50610943611cd9565b6040516109509190613bbb565b60405180910390f35b34801561096557600080fd5b50610980600480360381019061097b91906139bb565b611cdf565b60405161098d9190613963565b60405180910390f35b3480156109a257600080fd5b506109bd60048036038101906109b891906139bb565b611f8e565b005b3480156109cb57600080fd5b506109e660048036038101906109e1919061409e565b611fa3565b6040516109f39190613bbb565b60405180910390f35b348015610a0857600080fd5b50610a236004803603810190610a1e919061415c565b611fcf565b604051610a3091906138b8565b60405180910390f35b348015610a4557600080fd5b50610a606004803603810190610a5b91906139bb565b612063565b604051610a6d91906141f1565b60405180910390f35b348015610a8257600080fd5b50610a9d6004803603810190610a989190613bd6565b61210d565b005b348015610aab57600080fd5b50610ac66004803603810190610ac19190613e9d565b612190565b005b348015610ad457600080fd5b50610aef6004803603810190610aea9190613d28565b612289565b604051610afc9190613bbb565b60405180910390f35b348015610b1157600080fd5b50610b1a6122ba565b604051610b279190614234565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bfb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c6357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c799061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061427e565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b5050505050905090565b6000610d07826122e0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4d8261177f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490614321565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ddc61232b565b73ffffffffffffffffffffffffffffffffffffffff161480610e0b5750610e0a81610e0561232b565b611fcf565b5b610e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e41906143b3565b60405180910390fd5b610e548383612333565b505050565b600080610e65886123ec565b9050610e758782888888886124de565b809150509695505050505050565b6000600980549050905090565b610e98612529565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f32919061444b565b604051602081830303815290604052805190602001209050919050565b610f60610f5a61232b565b826125a7565b610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906144e3565b60405180910390fd5b610faa83838361263c565b505050565b6000610fba8361197a565b8210610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff290614575565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61105c612529565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110eb612529565b6002600b5403611130576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611127906145e1565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161116390614632565b60006040518083038185875af1925050503d80600081146111a0576040519150601f19603f3d011682016040523d82523d6000602084013e6111a5565b606091505b50509050806111b357600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111e29190613bbb565b60405180910390a150506001600b81905550565b6111fe612529565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f8da1c48aefffe2a2520f3e707937e3254d532a0905d345e539532599d2a0564c60405160405180910390a250565b6112a083838360405180602001604052806000815250611bac565b505050565b6112b66112b061232b565b826125a7565b6112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906144e3565b60405180910390fd5b6112fe816128a2565b50565b600060116000838152602001908152602001600020805490509050919050565b600061135430876040516020016113399291906146b0565b60405160208183030381529060405280519060200120610f1f565b9050848114611398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138f9061474e565b60405180910390fd5b6000600186868686604051600081526020016040526040516113bd949392919061477d565b6020604051602081039080840390855afa1580156113df573d6000803e3d6000fd5b505050602060405103519050601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114729061485a565b60405180910390fd5b600015156012600089815260200190815260200160002060009054906101000a900460ff161515146114e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d9906148ec565b60405180910390fd5b50505050505050565b60006114f6826129bf565b9050919050565b6000611507610e83565b8210611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f9061497e565b60405180910390fd5b6009828154811061155c5761155b61499e565b5b90600052602060002001549050919050565b60126020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161590614a3f565b60405180910390fd5b6011600082815260200190815260200160002082908060018154018082558091505060019003906000526020600020016000909190919091505580827f67c5bcaefda7c1381ded3fc61dbb8e693cef5b368cd356324bcc2b1aa791448c60405160405180910390a35050565b6000600f5434146116d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c790614aab565b60405180910390fd5b60006116db836123ec565b90506116e78133612a2b565b80915050919050565b6116f8612529565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181e90614b17565b60405180910390fd5b80915050919050565b6000600f543414611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90614aab565b60405180910390fd5b6000611881846123ec565b905061188d8130612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff8111156118e8576118e7613d72565b5b6040519080825280602002602001820160405280156119165781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161193593929190614bf5565b600060405180830381600087803b15801561194f57600080fd5b505af1158015611963573d6000803e3d6000fd5b50505050611970816128a2565b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e190614cac565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611a39612529565b611a436000612b57565b565b611a4d612529565b80600f819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611a839190613bbb565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611aed9061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054611b199061427e565b8015611b665780601f10611b3b57610100808354040283529160200191611b66565b820191906000526020600020905b815481529060010190602001808311611b4957829003601f168201915b5050505050905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611ba8611ba161232b565b8383612c1d565b5050565b611bbd611bb761232b565b836125a7565b611bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf3906144e3565b60405180910390fd5b611c0884848484612d89565b50505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b8152600401611c919190613bbb565b602060405180830381865afa158015611cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd29190614ce1565b9050919050565b600f5481565b6060611d1f6040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878846040518263ffffffff1660e01b8152600401611d7c9190613bbb565b600060405180830381865afa158015611d99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611dc29190614d7e565b9050611e026040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0856040518263ffffffff1660e01b8152600401611e5f9190613bbb565b602060405180830381865afa158015611e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea09190614ce1565b9050611ee06040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612de5565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611f3f93929190614dc7565b600060405180830381865afa158015611f5c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f859190614ea6565b92505050919050565b611f96612529565b611fa08133612a2b565b50565b600080611faf896123ec565b9050611fc088828989898989612e7e565b80915050979650505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016120c09190613bbb565b600060405180830381865afa1580156120dd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121069190614d7e565b9050919050565b612115612529565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612184576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217b90614f61565b60405180910390fd5b61218d81612b57565b50565b612198612529565b6121a28230612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788383600067ffffffffffffffff8111156121fd576121fc613d72565b5b60405190808252806020026020018201604052801561222b5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161224a93929190614bf5565b600060405180830381600087803b15801561226457600080fd5b505af1158015612278573d6000803e3d6000fd5b50505050612285826128a2565b5050565b601160205281600052604060002081815481106122a557600080fd5b90600052602060002001600091509150505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6122e9816129bf565b612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614b17565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166123a68361177f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080601160008481526020019081526020016000208054905011612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90614ff3565b60405180910390fd5b6000601160008481526020019081526020016000206001601160008681526020019081526020016000208054905061247e9190615042565b8154811061248f5761248e61499e565b5b90600052602060002001549050601160008481526020019081526020016000208054806124bf576124be615076565b5b6001900381819060005260206000200160009055905580915050919050565b6124eb8685858585611321565b6124f58533612a2b565b60016012600088815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b61253161232b565b73ffffffffffffffffffffffffffffffffffffffff1661254f611a8e565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259c906150f1565b60405180910390fd5b565b6000806125b38361177f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f557506125f48185611fcf565b5b8061263357508373ffffffffffffffffffffffffffffffffffffffff1661261b84610cfc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661265c8261177f565b73ffffffffffffffffffffffffffffffffffffffff16146126b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a990615183565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271890615215565b60405180910390fd5b61272c838383612fad565b612737600082612333565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127879190615042565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127de9190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461289d838383612fbd565b505050565b60006128ad8261177f565b90506128bb81600084612fad565b6128c6600083612333565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129169190615042565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129bb81600084612fbd565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301c6d035836040518263ffffffff1660e01b8152600401612a869190613bbb565b602060405180830381865afa158015612aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac7919061527e565b612b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afd906152f7565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b4857612b438183612fc2565b612b53565b612b52818361319b565b5b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8290615363565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612d7c91906138b8565b60405180910390a3505050565b612d9484848461263c565b612da0848484846131b9565b612ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd6906153f5565b60405180910390fd5b50505050565b612e7b81604051602401612df99190613963565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613340565b50565b612e8b8785858585611321565b612e958630612a2b565b60016012600089815260200190815260200160002060006101000a81548160ff021916908315150217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788787600067ffffffffffffffff811115612f1c57612f1b613d72565b5b604051908082528060200260200182016040528015612f4a5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b8152600401612f6993929190614bf5565b600060405180830381600087803b158015612f8357600080fd5b505af1158015612f97573d6000803e3d6000fd5b50505050612fa4866128a2565b50505050505050565b612fb8838383613369565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161302890615461565b60405180910390fd5b61303a816129bf565b1561307a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613071906154cd565b60405180910390fd5b61308660008383612fad565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130d69190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461319760008383612fbd565b5050565b6131b582826040518060200160405280600081525061347b565b5050565b60006131da8473ffffffffffffffffffffffffffffffffffffffff166134d6565b15613333578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261320361232b565b8786866040518563ffffffff1660e01b815260040161322594939291906154ed565b6020604051808303816000875af192505050801561326157506040513d601f19601f8201168201806040525081019061325e919061554e565b60015b6132e3573d8060008114613291576040519150601f19603f3d011682016040523d82523d6000602084013e613296565b606091505b5060008151036132db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d2906153f5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613338565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6133748383836134f9565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133b6576133b1816134fe565b6133f5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133f4576133f38382613547565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361343757613432816136b4565b613476565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614613475576134748282613785565b5b5b505050565b6134858383612fc2565b61349260008484846131b9565b6134d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134c8906153f5565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135548461197a565b61355e9190615042565b9050600060086000848152602001908152602001600020549050818114613643576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506136c89190615042565b90506000600a60008481526020019081526020016000205490506000600983815481106136f8576136f761499e565b5b90600052602060002001549050806009838154811061371a5761371961499e565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061376957613768615076565b5b6001900381819060005260206000200160009055905550505050565b60006137908361197a565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384d81613818565b811461385857600080fd5b50565b60008135905061386a81613844565b92915050565b6000602082840312156138865761388561380e565b5b60006138948482850161385b565b91505092915050565b60008115159050919050565b6138b28161389d565b82525050565b60006020820190506138cd60008301846138a9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561390d5780820151818401526020810190506138f2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613935826138d3565b61393f81856138de565b935061394f8185602086016138ef565b61395881613919565b840191505092915050565b6000602082019050818103600083015261397d818461392a565b905092915050565b6000819050919050565b61399881613985565b81146139a357600080fd5b50565b6000813590506139b58161398f565b92915050565b6000602082840312156139d1576139d061380e565b5b60006139df848285016139a6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a13826139e8565b9050919050565b613a2381613a08565b82525050565b6000602082019050613a3e6000830184613a1a565b92915050565b613a4d81613a08565b8114613a5857600080fd5b50565b600081359050613a6a81613a44565b92915050565b60008060408385031215613a8757613a8661380e565b5b6000613a9585828601613a5b565b9250506020613aa6858286016139a6565b9150509250929050565b6000819050919050565b613ac381613ab0565b8114613ace57600080fd5b50565b600081359050613ae081613aba565b92915050565b600060ff82169050919050565b613afc81613ae6565b8114613b0757600080fd5b50565b600081359050613b1981613af3565b92915050565b60008060008060008060c08789031215613b3c57613b3b61380e565b5b6000613b4a89828a016139a6565b9650506020613b5b89828a016139a6565b9550506040613b6c89828a01613ad1565b9450506060613b7d89828a01613b0a565b9350506080613b8e89828a01613ad1565b92505060a0613b9f89828a01613ad1565b9150509295509295509295565b613bb581613985565b82525050565b6000602082019050613bd06000830184613bac565b92915050565b600060208284031215613bec57613beb61380e565b5b6000613bfa84828501613a5b565b91505092915050565b600060208284031215613c1957613c1861380e565b5b6000613c2784828501613ad1565b91505092915050565b613c3981613ab0565b82525050565b6000602082019050613c546000830184613c30565b92915050565b600080600060608486031215613c7357613c7261380e565b5b6000613c8186828701613a5b565b9350506020613c9286828701613a5b565b9250506040613ca3868287016139a6565b9150509250925092565b600080600080600060a08688031215613cc957613cc861380e565b5b6000613cd7888289016139a6565b9550506020613ce888828901613ad1565b9450506040613cf988828901613b0a565b9350506060613d0a88828901613ad1565b9250506080613d1b88828901613ad1565b9150509295509295909350565b60008060408385031215613d3f57613d3e61380e565b5b6000613d4d858286016139a6565b9250506020613d5e858286016139a6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613daa82613919565b810181811067ffffffffffffffff82111715613dc957613dc8613d72565b5b80604052505050565b6000613ddc613804565b9050613de88282613da1565b919050565b600067ffffffffffffffff821115613e0857613e07613d72565b5b613e1182613919565b9050602081019050919050565b82818337600083830152505050565b6000613e40613e3b84613ded565b613dd2565b905082815260208101848484011115613e5c57613e5b613d6d565b5b613e67848285613e1e565b509392505050565b600082601f830112613e8457613e83613d68565b5b8135613e94848260208601613e2d565b91505092915050565b60008060408385031215613eb457613eb361380e565b5b6000613ec2858286016139a6565b925050602083013567ffffffffffffffff811115613ee357613ee2613813565b5b613eef85828601613e6f565b9150509250929050565b6000819050919050565b6000613f1e613f19613f14846139e8565b613ef9565b6139e8565b9050919050565b6000613f3082613f03565b9050919050565b6000613f4282613f25565b9050919050565b613f5281613f37565b82525050565b6000602082019050613f6d6000830184613f49565b92915050565b6000613f7e82613f25565b9050919050565b613f8e81613f73565b82525050565b6000602082019050613fa96000830184613f85565b92915050565b613fb88161389d565b8114613fc357600080fd5b50565b600081359050613fd581613faf565b92915050565b60008060408385031215613ff257613ff161380e565b5b600061400085828601613a5b565b925050602061401185828601613fc6565b9150509250929050565b600080600080608085870312156140355761403461380e565b5b600061404387828801613a5b565b945050602061405487828801613a5b565b9350506040614065878288016139a6565b925050606085013567ffffffffffffffff81111561408657614085613813565b5b61409287828801613e6f565b91505092959194509250565b600080600080600080600060e0888a0312156140bd576140bc61380e565b5b60006140cb8a828b016139a6565b97505060206140dc8a828b016139a6565b965050604088013567ffffffffffffffff8111156140fd576140fc613813565b5b6141098a828b01613e6f565b955050606061411a8a828b01613ad1565b945050608061412b8a828b01613b0a565b93505060a061413c8a828b01613ad1565b92505060c061414d8a828b01613ad1565b91505092959891949750929550565b600080604083850312156141735761417261380e565b5b600061418185828601613a5b565b925050602061419285828601613a5b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60006141c38261419c565b6141cd81856141a7565b93506141dd8185602086016138ef565b6141e681613919565b840191505092915050565b6000602082019050818103600083015261420b81846141b8565b905092915050565b600061421e82613f25565b9050919050565b61422e81614213565b82525050565b60006020820190506142496000830184614225565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061429657607f821691505b6020821081036142a9576142a861424f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061430b6021836138de565b9150614316826142af565b604082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061439d603e836138de565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614414601c836143d3565b915061441f826143de565b601c82019050919050565b6000819050919050565b61444561444082613ab0565b61442a565b82525050565b600061445682614407565b91506144628284614434565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006144cd602e836138de565b91506144d882614471565b604082019050919050565b600060208201905081810360008301526144fc816144c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061455f602b836138de565b915061456a82614503565b604082019050919050565b6000602082019050818103600083015261458e81614552565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145cb601f836138de565b91506145d682614595565b602082019050919050565b600060208201905081810360008301526145fa816145be565b9050919050565b600081905092915050565b50565b600061461c600083614601565b91506146278261460c565b600082019050919050565b600061463d8261460f565b9150819050919050565b60008160601b9050919050565b600061465f82614647565b9050919050565b600061467182614654565b9050919050565b61468961468482613a08565b614666565b82525050565b6000819050919050565b6146aa6146a582613985565b61468f565b82525050565b60006146bc8285614678565b6014820191506146cc8284614699565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b6000614738603c836138de565b9150614743826146dc565b604082019050919050565b600060208201905081810360008301526147678161472b565b9050919050565b61477781613ae6565b82525050565b60006080820190506147926000830187613c30565b61479f602083018661476e565b6147ac6040830185613c30565b6147b96060830184613c30565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b60006148446041836138de565b915061484f826147c2565b606082019050919050565b6000602082019050818103600083015261487381614837565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b60006148d6602b836138de565b91506148e18261487a565b604082019050919050565b60006020820190508181036000830152614905816148c9565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614968602c836138de565b91506149738261490c565b604082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4f6e6c792074686520726f7574696e6720636f6e74726163742063616e20636160008201527f6c6c20746869732066756e6374696f6e00000000000000000000000000000000602082015250565b6000614a296030836138de565b9150614a34826149cd565b604082019050919050565b60006020820190508181036000830152614a5881614a1c565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614a95601e836138de565b9150614aa082614a5f565b602082019050919050565b60006020820190508181036000830152614ac481614a88565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b016018836138de565b9150614b0c82614acb565b602082019050919050565b60006020820190508181036000830152614b3081614af4565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614b6c81613985565b82525050565b6000614b7e8383614b63565b60208301905092915050565b6000602082019050919050565b6000614ba282614b37565b614bac8185614b42565b9350614bb783614b53565b8060005b83811015614be8578151614bcf8882614b72565b9750614bda83614b8a565b925050600181019050614bbb565b5085935050505092915050565b6000606082019050614c0a6000830186613bac565b8181036020830152614c1c81856141b8565b90508181036040830152614c308184614b97565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614c966029836138de565b9150614ca182614c3a565b604082019050919050565b60006020820190508181036000830152614cc581614c89565b9050919050565b600081519050614cdb81613a44565b92915050565b600060208284031215614cf757614cf661380e565b5b6000614d0584828501614ccc565b91505092915050565b6000614d21614d1c84613ded565b613dd2565b905082815260208101848484011115614d3d57614d3c613d6d565b5b614d488482856138ef565b509392505050565b600082601f830112614d6557614d64613d68565b5b8151614d75848260208601614d0e565b91505092915050565b600060208284031215614d9457614d9361380e565b5b600082015167ffffffffffffffff811115614db257614db1613813565b5b614dbe84828501614d50565b91505092915050565b6000606082019050614ddc6000830186613bac565b8181036020830152614dee81856141b8565b9050614dfd6040830184613a1a565b949350505050565b600067ffffffffffffffff821115614e2057614e1f613d72565b5b614e2982613919565b9050602081019050919050565b6000614e49614e4484614e05565b613dd2565b905082815260208101848484011115614e6557614e64613d6d565b5b614e708482856138ef565b509392505050565b600082601f830112614e8d57614e8c613d68565b5b8151614e9d848260208601614e36565b91505092915050565b600060208284031215614ebc57614ebb61380e565b5b600082015167ffffffffffffffff811115614eda57614ed9613813565b5b614ee684828501614e78565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614f4b6026836138de565b9150614f5682614eef565b604082019050919050565b60006020820190508181036000830152614f7a81614f3e565b9050919050565b7f546865726520617265206e6f20756e6d696e74656420726f7574656420746f6b60008201527f656e2069647320746f206d696e74000000000000000000000000000000000000602082015250565b6000614fdd602e836138de565b9150614fe882614f81565b604082019050919050565b6000602082019050818103600083015261500c81614fd0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061504d82613985565b915061505883613985565b92508282039050818111156150705761506f615013565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150db6020836138de565b91506150e6826150a5565b602082019050919050565b6000602082019050818103600083015261510a816150ce565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061516d6025836138de565b915061517882615111565b604082019050919050565b6000602082019050818103600083015261519c81615160565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006151ff6024836138de565b915061520a826151a3565b604082019050919050565b6000602082019050818103600083015261522e816151f2565b9050919050565b600061524082613985565b915061524b83613985565b925082820190508082111561526357615262615013565b5b92915050565b60008151905061527881613faf565b92915050565b6000602082840312156152945761529361380e565b5b60006152a284828501615269565b91505092915050565b7f5468697320504b5020686173206e6f74206265656e20726f7574656420796574600082015250565b60006152e16020836138de565b91506152ec826152ab565b602082019050919050565b60006020820190508181036000830152615310816152d4565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061534d6019836138de565b915061535882615317565b602082019050919050565b6000602082019050818103600083015261537c81615340565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006153df6032836138de565b91506153ea82615383565b604082019050919050565b6000602082019050818103600083015261540e816153d2565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061544b6020836138de565b915061545682615415565b602082019050919050565b6000602082019050818103600083015261547a8161543e565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006154b7601c836138de565b91506154c282615481565b602082019050919050565b600060208201905081810360008301526154e6816154aa565b9050919050565b60006080820190506155026000830187613a1a565b61550f6020830186613a1a565b61551c6040830185613bac565b818103606083015261552e81846141b8565b905095945050505050565b60008151905061554881613844565b92915050565b6000602082840312156155645761556361380e565b5b600061557284828501615539565b9150509291505056fea2646970667358221220aef3c8e873f7d7ca9093f4651870210e216de877ed78dc08f3232820670913f364736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c80636352211e1161014f578063b94a2102116100c1578063e985e9c51161007a578063e985e9c5146109fc578063ef6fd87814610a39578063f2fde38b14610a76578063f556aeb114610a9f578063f70e72ef14610ac8578063f887ea4014610b055761027d565b8063b94a2102146108c6578063bd4986a0146108f1578063bdb4b8481461092e578063c87b56dd14610959578063d343682614610996578063d7b0398b146109bf5761027d565b80638da5cb5b116101135780638da5cb5b146107c85780639388f12e146107f357806395d89b411461081e57806397016f3f14610849578063a22cb46514610874578063b88d4fde1461089d5761027d565b80636352211e146106de57806366a306d71461071b57806370a082311461074b578063715018a6146107885780638545f4ea1461079f5761027d565b80633ccfd60b116101f35780634f558e79116101ac5780634f558e79146105a55780634f6ccce7146105e257806356e3a1ae1461061f5780635c110a9c1461065c5780635d228b16146106855780635f49663c146106b55761027d565b80633ccfd60b146104ad57806341cb87fc146104c457806342842e0e146104ed57806342966c681461051657806342dd8fcb1461053f5780634c19eae61461057c5761027d565b806318160ddd1161024557806318160ddd1461038d5780631ea89a22146103b85780631f275713146103e157806323b872dd1461041e5780632f745c59146104475780633b189852146104845761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b3146103275780631582391c14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613870565b610b30565b6040516102b691906138b8565b60405180910390f35b3480156102cb57600080fd5b506102d4610c6a565b6040516102e19190613963565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c91906139bb565b610cfc565b60405161031e9190613a29565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613a70565b610d42565b005b34801561035c57600080fd5b5061037760048036038101906103729190613b1f565b610e59565b6040516103849190613bbb565b60405180910390f35b34801561039957600080fd5b506103a2610e83565b6040516103af9190613bbb565b60405180910390f35b3480156103c457600080fd5b506103df60048036038101906103da9190613bd6565b610e90565b005b3480156103ed57600080fd5b5061040860048036038101906104039190613c03565b610f1f565b6040516104159190613c3f565b60405180910390f35b34801561042a57600080fd5b5061044560048036038101906104409190613c5a565b610f4f565b005b34801561045357600080fd5b5061046e60048036038101906104699190613a70565b610faf565b60405161047b9190613bbb565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190613bd6565b611054565b005b3480156104b957600080fd5b506104c26110e3565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190613bd6565b6111f6565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613c5a565b611285565b005b34801561052257600080fd5b5061053d600480360381019061053891906139bb565b6112a5565b005b34801561054b57600080fd5b50610566600480360381019061056191906139bb565b611301565b6040516105739190613bbb565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e9190613cad565b611321565b005b3480156105b157600080fd5b506105cc60048036038101906105c791906139bb565b6114eb565b6040516105d991906138b8565b60405180910390f35b3480156105ee57600080fd5b50610609600480360381019061060491906139bb565b6114fd565b6040516106169190613bbb565b60405180910390f35b34801561062b57600080fd5b50610646600480360381019061064191906139bb565b61156e565b60405161065391906138b8565b60405180910390f35b34801561066857600080fd5b50610683600480360381019061067e9190613d28565b61158e565b005b61069f600480360381019061069a91906139bb565b61168a565b6040516106ac9190613bbb565b60405180910390f35b3480156106c157600080fd5b506106dc60048036038101906106d79190613bd6565b6116f0565b005b3480156106ea57600080fd5b50610705600480360381019061070091906139bb565b61177f565b6040516107129190613a29565b60405180910390f35b61073560048036038101906107309190613e9d565b611830565b6040516107429190613bbb565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613bd6565b61197a565b60405161077f9190613bbb565b60405180910390f35b34801561079457600080fd5b5061079d611a31565b005b3480156107ab57600080fd5b506107c660048036038101906107c191906139bb565b611a45565b005b3480156107d457600080fd5b506107dd611a8e565b6040516107ea9190613a29565b60405180910390f35b3480156107ff57600080fd5b50610808611ab8565b6040516108159190613f58565b60405180910390f35b34801561082a57600080fd5b50610833611ade565b6040516108409190613963565b60405180910390f35b34801561085557600080fd5b5061085e611b70565b60405161086b9190613f94565b60405180910390f35b34801561088057600080fd5b5061089b60048036038101906108969190613fdb565b611b96565b005b3480156108a957600080fd5b506108c460048036038101906108bf919061401b565b611bac565b005b3480156108d257600080fd5b506108db611c0e565b6040516108e89190613a29565b60405180910390f35b3480156108fd57600080fd5b50610918600480360381019061091391906139bb565b611c34565b6040516109259190613a29565b60405180910390f35b34801561093a57600080fd5b50610943611cd9565b6040516109509190613bbb565b60405180910390f35b34801561096557600080fd5b50610980600480360381019061097b91906139bb565b611cdf565b60405161098d9190613963565b60405180910390f35b3480156109a257600080fd5b506109bd60048036038101906109b891906139bb565b611f8e565b005b3480156109cb57600080fd5b506109e660048036038101906109e1919061409e565b611fa3565b6040516109f39190613bbb565b60405180910390f35b348015610a0857600080fd5b50610a236004803603810190610a1e919061415c565b611fcf565b604051610a3091906138b8565b60405180910390f35b348015610a4557600080fd5b50610a606004803603810190610a5b91906139bb565b612063565b604051610a6d91906141f1565b60405180910390f35b348015610a8257600080fd5b50610a9d6004803603810190610a989190613bd6565b61210d565b005b348015610aab57600080fd5b50610ac66004803603810190610ac19190613e9d565b612190565b005b348015610ad457600080fd5b50610aef6004803603810190610aea9190613d28565b612289565b604051610afc9190613bbb565b60405180910390f35b348015610b1157600080fd5b50610b1a6122ba565b604051610b279190614234565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bfb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c6357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c799061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061427e565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b5050505050905090565b6000610d07826122e0565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d4d8261177f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490614321565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610ddc61232b565b73ffffffffffffffffffffffffffffffffffffffff161480610e0b5750610e0a81610e0561232b565b611fcf565b5b610e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e41906143b3565b60405180910390fd5b610e548383612333565b505050565b600080610e65886123ec565b9050610e758782888888886124de565b809150509695505050505050565b6000600980549050905090565b610e98612529565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f32919061444b565b604051602081830303815290604052805190602001209050919050565b610f60610f5a61232b565b826125a7565b610f9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f96906144e3565b60405180910390fd5b610faa83838361263c565b505050565b6000610fba8361197a565b8210610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff290614575565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b61105c612529565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110eb612529565b6002600b5403611130576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611127906145e1565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161116390614632565b60006040518083038185875af1925050503d80600081146111a0576040519150601f19603f3d011682016040523d82523d6000602084013e6111a5565b606091505b50509050806111b357600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111e29190613bbb565b60405180910390a150506001600b81905550565b6111fe612529565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f8da1c48aefffe2a2520f3e707937e3254d532a0905d345e539532599d2a0564c60405160405180910390a250565b6112a083838360405180602001604052806000815250611bac565b505050565b6112b66112b061232b565b826125a7565b6112f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ec906144e3565b60405180910390fd5b6112fe816128a2565b50565b600060116000838152602001908152602001600020805490509050919050565b600061135430876040516020016113399291906146b0565b60405160208183030381529060405280519060200120610f1f565b9050848114611398576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138f9061474e565b60405180910390fd5b6000600186868686604051600081526020016040526040516113bd949392919061477d565b6020604051602081039080840390855afa1580156113df573d6000803e3d6000fd5b505050602060405103519050601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461147b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114729061485a565b60405180910390fd5b600015156012600089815260200190815260200160002060009054906101000a900460ff161515146114e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d9906148ec565b60405180910390fd5b50505050505050565b60006114f6826129bf565b9050919050565b6000611507610e83565b8210611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f9061497e565b60405180910390fd5b6009828154811061155c5761155b61499e565b5b90600052602060002001549050919050565b60126020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461161e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161590614a3f565b60405180910390fd5b6011600082815260200190815260200160002082908060018154018082558091505060019003906000526020600020016000909190919091505580827f67c5bcaefda7c1381ded3fc61dbb8e693cef5b368cd356324bcc2b1aa791448c60405160405180910390a35050565b6000600f5434146116d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c790614aab565b60405180910390fd5b60006116db836123ec565b90506116e78133612a2b565b80915050919050565b6116f8612529565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611827576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181e90614b17565b60405180910390fd5b80915050919050565b6000600f543414611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90614aab565b60405180910390fd5b6000611881846123ec565b905061188d8130612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff8111156118e8576118e7613d72565b5b6040519080825280602002602001820160405280156119165781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161193593929190614bf5565b600060405180830381600087803b15801561194f57600080fd5b505af1158015611963573d6000803e3d6000fd5b50505050611970816128a2565b8091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e190614cac565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611a39612529565b611a436000612b57565b565b611a4d612529565b80600f819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611a839190613bbb565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611aed9061427e565b80601f0160208091040260200160405190810160405280929190818152602001828054611b199061427e565b8015611b665780601f10611b3b57610100808354040283529160200191611b66565b820191906000526020600020905b815481529060010190602001808311611b4957829003601f168201915b5050505050905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611ba8611ba161232b565b8383612c1d565b5050565b611bbd611bb761232b565b836125a7565b611bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf3906144e3565b60405180910390fd5b611c0884848484612d89565b50505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b8152600401611c919190613bbb565b602060405180830381865afa158015611cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd29190614ce1565b9050919050565b600f5481565b6060611d1f6040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878846040518263ffffffff1660e01b8152600401611d7c9190613bbb565b600060405180830381865afa158015611d99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611dc29190614d7e565b9050611e026040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612de5565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0856040518263ffffffff1660e01b8152600401611e5f9190613bbb565b602060405180830381865afa158015611e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea09190614ce1565b9050611ee06040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612de5565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611f3f93929190614dc7565b600060405180830381865afa158015611f5c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f859190614ea6565b92505050919050565b611f96612529565b611fa08133612a2b565b50565b600080611faf896123ec565b9050611fc088828989898989612e7e565b80915050979650505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016120c09190613bbb565b600060405180830381865afa1580156120dd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121069190614d7e565b9050919050565b612115612529565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612184576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217b90614f61565b60405180910390fd5b61218d81612b57565b50565b612198612529565b6121a28230612a2b565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788383600067ffffffffffffffff8111156121fd576121fc613d72565b5b60405190808252806020026020018201604052801561222b5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161224a93929190614bf5565b600060405180830381600087803b15801561226457600080fd5b505af1158015612278573d6000803e3d6000fd5b50505050612285826128a2565b5050565b601160205281600052604060002081815481106122a557600080fd5b90600052602060002001600091509150505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6122e9816129bf565b612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614b17565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166123a68361177f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080601160008481526020019081526020016000208054905011612446576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243d90614ff3565b60405180910390fd5b6000601160008481526020019081526020016000206001601160008681526020019081526020016000208054905061247e9190615042565b8154811061248f5761248e61499e565b5b90600052602060002001549050601160008481526020019081526020016000208054806124bf576124be615076565b5b6001900381819060005260206000200160009055905580915050919050565b6124eb8685858585611321565b6124f58533612a2b565b60016012600088815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b61253161232b565b73ffffffffffffffffffffffffffffffffffffffff1661254f611a8e565b73ffffffffffffffffffffffffffffffffffffffff16146125a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259c906150f1565b60405180910390fd5b565b6000806125b38361177f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806125f557506125f48185611fcf565b5b8061263357508373ffffffffffffffffffffffffffffffffffffffff1661261b84610cfc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661265c8261177f565b73ffffffffffffffffffffffffffffffffffffffff16146126b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a990615183565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161271890615215565b60405180910390fd5b61272c838383612fad565b612737600082612333565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127879190615042565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127de9190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461289d838383612fbd565b505050565b60006128ad8261177f565b90506128bb81600084612fad565b6128c6600083612333565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129169190615042565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129bb81600084612fbd565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166301c6d035836040518263ffffffff1660e01b8152600401612a869190613bbb565b602060405180830381865afa158015612aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac7919061527e565b612b06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afd906152f7565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b4857612b438183612fc2565b612b53565b612b52818361319b565b5b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8290615363565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612d7c91906138b8565b60405180910390a3505050565b612d9484848461263c565b612da0848484846131b9565b612ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd6906153f5565b60405180910390fd5b50505050565b612e7b81604051602401612df99190613963565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613340565b50565b612e8b8785858585611321565b612e958630612a2b565b60016012600089815260200190815260200160002060006101000a81548160ff021916908315150217905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788787600067ffffffffffffffff811115612f1c57612f1b613d72565b5b604051908082528060200260200182016040528015612f4a5781602001602082028036833780820191505090505b506040518463ffffffff1660e01b8152600401612f6993929190614bf5565b600060405180830381600087803b158015612f8357600080fd5b505af1158015612f97573d6000803e3d6000fd5b50505050612fa4866128a2565b50505050505050565b612fb8838383613369565b505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161302890615461565b60405180910390fd5b61303a816129bf565b1561307a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613071906154cd565b60405180910390fd5b61308660008383612fad565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130d69190615235565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461319760008383612fbd565b5050565b6131b582826040518060200160405280600081525061347b565b5050565b60006131da8473ffffffffffffffffffffffffffffffffffffffff166134d6565b15613333578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261320361232b565b8786866040518563ffffffff1660e01b815260040161322594939291906154ed565b6020604051808303816000875af192505050801561326157506040513d601f19601f8201168201806040525081019061325e919061554e565b60015b6132e3573d8060008114613291576040519150601f19603f3d011682016040523d82523d6000602084013e613296565b606091505b5060008151036132db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d2906153f5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050613338565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b6133748383836134f9565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133b6576133b1816134fe565b6133f5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133f4576133f38382613547565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361343757613432816136b4565b613476565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614613475576134748282613785565b5b5b505050565b6134858383612fc2565b61349260008484846131b9565b6134d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134c8906153f5565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016135548461197a565b61355e9190615042565b9050600060086000848152602001908152602001600020549050818114613643576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506136c89190615042565b90506000600a60008481526020019081526020016000205490506000600983815481106136f8576136f761499e565b5b90600052602060002001549050806009838154811061371a5761371961499e565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061376957613768615076565b5b6001900381819060005260206000200160009055905550505050565b60006137908361197a565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61384d81613818565b811461385857600080fd5b50565b60008135905061386a81613844565b92915050565b6000602082840312156138865761388561380e565b5b60006138948482850161385b565b91505092915050565b60008115159050919050565b6138b28161389d565b82525050565b60006020820190506138cd60008301846138a9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561390d5780820151818401526020810190506138f2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613935826138d3565b61393f81856138de565b935061394f8185602086016138ef565b61395881613919565b840191505092915050565b6000602082019050818103600083015261397d818461392a565b905092915050565b6000819050919050565b61399881613985565b81146139a357600080fd5b50565b6000813590506139b58161398f565b92915050565b6000602082840312156139d1576139d061380e565b5b60006139df848285016139a6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a13826139e8565b9050919050565b613a2381613a08565b82525050565b6000602082019050613a3e6000830184613a1a565b92915050565b613a4d81613a08565b8114613a5857600080fd5b50565b600081359050613a6a81613a44565b92915050565b60008060408385031215613a8757613a8661380e565b5b6000613a9585828601613a5b565b9250506020613aa6858286016139a6565b9150509250929050565b6000819050919050565b613ac381613ab0565b8114613ace57600080fd5b50565b600081359050613ae081613aba565b92915050565b600060ff82169050919050565b613afc81613ae6565b8114613b0757600080fd5b50565b600081359050613b1981613af3565b92915050565b60008060008060008060c08789031215613b3c57613b3b61380e565b5b6000613b4a89828a016139a6565b9650506020613b5b89828a016139a6565b9550506040613b6c89828a01613ad1565b9450506060613b7d89828a01613b0a565b9350506080613b8e89828a01613ad1565b92505060a0613b9f89828a01613ad1565b9150509295509295509295565b613bb581613985565b82525050565b6000602082019050613bd06000830184613bac565b92915050565b600060208284031215613bec57613beb61380e565b5b6000613bfa84828501613a5b565b91505092915050565b600060208284031215613c1957613c1861380e565b5b6000613c2784828501613ad1565b91505092915050565b613c3981613ab0565b82525050565b6000602082019050613c546000830184613c30565b92915050565b600080600060608486031215613c7357613c7261380e565b5b6000613c8186828701613a5b565b9350506020613c9286828701613a5b565b9250506040613ca3868287016139a6565b9150509250925092565b600080600080600060a08688031215613cc957613cc861380e565b5b6000613cd7888289016139a6565b9550506020613ce888828901613ad1565b9450506040613cf988828901613b0a565b9350506060613d0a88828901613ad1565b9250506080613d1b88828901613ad1565b9150509295509295909350565b60008060408385031215613d3f57613d3e61380e565b5b6000613d4d858286016139a6565b9250506020613d5e858286016139a6565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613daa82613919565b810181811067ffffffffffffffff82111715613dc957613dc8613d72565b5b80604052505050565b6000613ddc613804565b9050613de88282613da1565b919050565b600067ffffffffffffffff821115613e0857613e07613d72565b5b613e1182613919565b9050602081019050919050565b82818337600083830152505050565b6000613e40613e3b84613ded565b613dd2565b905082815260208101848484011115613e5c57613e5b613d6d565b5b613e67848285613e1e565b509392505050565b600082601f830112613e8457613e83613d68565b5b8135613e94848260208601613e2d565b91505092915050565b60008060408385031215613eb457613eb361380e565b5b6000613ec2858286016139a6565b925050602083013567ffffffffffffffff811115613ee357613ee2613813565b5b613eef85828601613e6f565b9150509250929050565b6000819050919050565b6000613f1e613f19613f14846139e8565b613ef9565b6139e8565b9050919050565b6000613f3082613f03565b9050919050565b6000613f4282613f25565b9050919050565b613f5281613f37565b82525050565b6000602082019050613f6d6000830184613f49565b92915050565b6000613f7e82613f25565b9050919050565b613f8e81613f73565b82525050565b6000602082019050613fa96000830184613f85565b92915050565b613fb88161389d565b8114613fc357600080fd5b50565b600081359050613fd581613faf565b92915050565b60008060408385031215613ff257613ff161380e565b5b600061400085828601613a5b565b925050602061401185828601613fc6565b9150509250929050565b600080600080608085870312156140355761403461380e565b5b600061404387828801613a5b565b945050602061405487828801613a5b565b9350506040614065878288016139a6565b925050606085013567ffffffffffffffff81111561408657614085613813565b5b61409287828801613e6f565b91505092959194509250565b600080600080600080600060e0888a0312156140bd576140bc61380e565b5b60006140cb8a828b016139a6565b97505060206140dc8a828b016139a6565b965050604088013567ffffffffffffffff8111156140fd576140fc613813565b5b6141098a828b01613e6f565b955050606061411a8a828b01613ad1565b945050608061412b8a828b01613b0a565b93505060a061413c8a828b01613ad1565b92505060c061414d8a828b01613ad1565b91505092959891949750929550565b600080604083850312156141735761417261380e565b5b600061418185828601613a5b565b925050602061419285828601613a5b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60006141c38261419c565b6141cd81856141a7565b93506141dd8185602086016138ef565b6141e681613919565b840191505092915050565b6000602082019050818103600083015261420b81846141b8565b905092915050565b600061421e82613f25565b9050919050565b61422e81614213565b82525050565b60006020820190506142496000830184614225565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061429657607f821691505b6020821081036142a9576142a861424f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061430b6021836138de565b9150614316826142af565b604082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061439d603e836138de565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614414601c836143d3565b915061441f826143de565b601c82019050919050565b6000819050919050565b61444561444082613ab0565b61442a565b82525050565b600061445682614407565b91506144628284614434565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006144cd602e836138de565b91506144d882614471565b604082019050919050565b600060208201905081810360008301526144fc816144c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061455f602b836138de565b915061456a82614503565b604082019050919050565b6000602082019050818103600083015261458e81614552565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006145cb601f836138de565b91506145d682614595565b602082019050919050565b600060208201905081810360008301526145fa816145be565b9050919050565b600081905092915050565b50565b600061461c600083614601565b91506146278261460c565b600082019050919050565b600061463d8261460f565b9150819050919050565b60008160601b9050919050565b600061465f82614647565b9050919050565b600061467182614654565b9050919050565b61468961468482613a08565b614666565b82525050565b6000819050919050565b6146aa6146a582613985565b61468f565b82525050565b60006146bc8285614678565b6014820191506146cc8284614699565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b6000614738603c836138de565b9150614743826146dc565b604082019050919050565b600060208201905081810360008301526147678161472b565b9050919050565b61477781613ae6565b82525050565b60006080820190506147926000830187613c30565b61479f602083018661476e565b6147ac6040830185613c30565b6147b96060830184613c30565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b60006148446041836138de565b915061484f826147c2565b606082019050919050565b6000602082019050818103600083015261487381614837565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b60006148d6602b836138de565b91506148e18261487a565b604082019050919050565b60006020820190508181036000830152614905816148c9565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614968602c836138de565b91506149738261490c565b604082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4f6e6c792074686520726f7574696e6720636f6e74726163742063616e20636160008201527f6c6c20746869732066756e6374696f6e00000000000000000000000000000000602082015250565b6000614a296030836138de565b9150614a34826149cd565b604082019050919050565b60006020820190508181036000830152614a5881614a1c565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614a95601e836138de565b9150614aa082614a5f565b602082019050919050565b60006020820190508181036000830152614ac481614a88565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614b016018836138de565b9150614b0c82614acb565b602082019050919050565b60006020820190508181036000830152614b3081614af4565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614b6c81613985565b82525050565b6000614b7e8383614b63565b60208301905092915050565b6000602082019050919050565b6000614ba282614b37565b614bac8185614b42565b9350614bb783614b53565b8060005b83811015614be8578151614bcf8882614b72565b9750614bda83614b8a565b925050600181019050614bbb565b5085935050505092915050565b6000606082019050614c0a6000830186613bac565b8181036020830152614c1c81856141b8565b90508181036040830152614c308184614b97565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614c966029836138de565b9150614ca182614c3a565b604082019050919050565b60006020820190508181036000830152614cc581614c89565b9050919050565b600081519050614cdb81613a44565b92915050565b600060208284031215614cf757614cf661380e565b5b6000614d0584828501614ccc565b91505092915050565b6000614d21614d1c84613ded565b613dd2565b905082815260208101848484011115614d3d57614d3c613d6d565b5b614d488482856138ef565b509392505050565b600082601f830112614d6557614d64613d68565b5b8151614d75848260208601614d0e565b91505092915050565b600060208284031215614d9457614d9361380e565b5b600082015167ffffffffffffffff811115614db257614db1613813565b5b614dbe84828501614d50565b91505092915050565b6000606082019050614ddc6000830186613bac565b8181036020830152614dee81856141b8565b9050614dfd6040830184613a1a565b949350505050565b600067ffffffffffffffff821115614e2057614e1f613d72565b5b614e2982613919565b9050602081019050919050565b6000614e49614e4484614e05565b613dd2565b905082815260208101848484011115614e6557614e64613d6d565b5b614e708482856138ef565b509392505050565b600082601f830112614e8d57614e8c613d68565b5b8151614e9d848260208601614e36565b91505092915050565b600060208284031215614ebc57614ebb61380e565b5b600082015167ffffffffffffffff811115614eda57614ed9613813565b5b614ee684828501614e78565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614f4b6026836138de565b9150614f5682614eef565b604082019050919050565b60006020820190508181036000830152614f7a81614f3e565b9050919050565b7f546865726520617265206e6f20756e6d696e74656420726f7574656420746f6b60008201527f656e2069647320746f206d696e74000000000000000000000000000000000000602082015250565b6000614fdd602e836138de565b9150614fe882614f81565b604082019050919050565b6000602082019050818103600083015261500c81614fd0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061504d82613985565b915061505883613985565b92508282039050818111156150705761506f615013565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150db6020836138de565b91506150e6826150a5565b602082019050919050565b6000602082019050818103600083015261510a816150ce565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061516d6025836138de565b915061517882615111565b604082019050919050565b6000602082019050818103600083015261519c81615160565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006151ff6024836138de565b915061520a826151a3565b604082019050919050565b6000602082019050818103600083015261522e816151f2565b9050919050565b600061524082613985565b915061524b83613985565b925082820190508082111561526357615262615013565b5b92915050565b60008151905061527881613faf565b92915050565b6000602082840312156152945761529361380e565b5b60006152a284828501615269565b91505092915050565b7f5468697320504b5020686173206e6f74206265656e20726f7574656420796574600082015250565b60006152e16020836138de565b91506152ec826152ab565b602082019050919050565b60006020820190508181036000830152615310816152d4565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061534d6019836138de565b915061535882615317565b602082019050919050565b6000602082019050818103600083015261537c81615340565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006153df6032836138de565b91506153ea82615383565b604082019050919050565b6000602082019050818103600083015261540e816153d2565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061544b6020836138de565b915061545682615415565b602082019050919050565b6000602082019050818103600083015261547a8161543e565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006154b7601c836138de565b91506154c282615481565b602082019050919050565b600060208201905081810360008301526154e6816154aa565b9050919050565b60006080820190506155026000830187613a1a565b61550f6020830186613a1a565b61551c6040830185613bac565b818103606083015261552e81846141b8565b905095945050505050565b60008151905061554881613844565b92915050565b6000602082840312156155645761556361380e565b5b600061557284828501615539565b9150509291505056fea2646970667358221220aef3c8e873f7d7ca9093f4651870210e216de877ed78dc08f3232820670913f364736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"routerAddress","type":"address"}],"name":"RouterAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurnNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"getUnmintedRoutedTokenIdCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurnNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurnSpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"mintNext","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintSpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"pkpRouted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract PubkeyRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"}],"name":"setRouterAddress","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"unmintedRoutedTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/PKPNFTMetadata.json b/deployments/mumbai_80001/PKPNFTMetadata.json deleted file mode 100644 index 93ea284..0000000 --- a/deployments/mumbai_80001/PKPNFTMetadata.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xBd2C17bd4f454d2Ea6310999f58909a51c743c31","bytecode":"0x608060405234801561001057600080fd5b506117de806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"buffer","type":"bytes"}],"name":"bytesToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"address","name":"ethAddress","type":"address"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/PKPPermissions.json b/deployments/mumbai_80001/PKPPermissions.json deleted file mode 100644 index c89001b..0000000 --- a/deployments/mumbai_80001/PKPPermissions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x64660262a3dC7Be3C40E1FBf6a728ab8eFCD4E32","bytecode":"0x60806040523480156200001157600080fd5b5060405162005087380380620050878339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b614e7080620002176000396000f3fe608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea2646970667358221220618278f306dbfced55fc066e4127744edb57870501ff568dc5f93167d38285c564736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea2646970667358221220618278f306dbfced55fc066e4127744edb57870501ff568dc5f93167d38285c564736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"userPubkey","type":"bytes"}],"name":"PermittedAuthMethodAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"}],"name":"PermittedAuthMethodRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"group","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootHashUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod","name":"authMethod","type":"tuple"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"addPermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"authMethods","outputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getAuthMethodId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedActions","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"maxScopeId","type":"uint256"}],"name":"getPermittedAuthMethodScopes","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAuthMethods","outputs":[{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getTokenIdsForAuthMethod","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getUserPubkeyForAuthMethod","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"isPermittedAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isPermittedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"isPermittedAuthMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"isPermittedAuthMethodScopePresent","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"removePermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"removePermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"removePermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"removePermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verifyState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool[]","name":"proofFlags","type":"bool[]"},{"internalType":"bytes32[]","name":"leaves","type":"bytes32[]"}],"name":"verifyStates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/PubkeyRouter.json b/deployments/mumbai_80001/PubkeyRouter.json deleted file mode 100644 index f00bc92..0000000 --- a/deployments/mumbai_80001/PubkeyRouter.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n PubkeyRouter public router;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _router) {\\n pkpNFT = PKPNFT(_pkpNft);\\n router = PubkeyRouter(_router);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(uint256 authMethodType, bytes memory id)\\n public\\n pure\\n returns (uint256)\\n {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(uint256 authMethodType, bytes calldata id)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(uint256 tokenId)\\n external\\n view\\n returns (AuthMethod[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(uint256 tokenId)\\n public\\n view\\n returns (bytes[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(uint256 tokenId)\\n public\\n view\\n returns (address[] memory)\\n {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(uint256 tokenId, address user)\\n public\\n view\\n returns (bool)\\n {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(uint256 tokenId, bytes calldata ipfsCID)\\n public\\n {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n function setRouterAddress(address newRouterAddress) public onlyOwner {\\n router = PubkeyRouter(newRouterAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.3;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.3\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10**stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10**stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(address stakerAddress)\\n public\\n view\\n returns (bool)\\n {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.epochlength\\n require(\\n block.number >= epoch.endBlock + epoch.epochLength,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n epoch.endBlock = block.number + epoch.epochLength;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10**stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress);\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(uint256 newKickPenaltyPercent)\\n public\\n onlyOwner\\n {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(address newResolverContractAddress)\\n public\\n onlyOwner\\n {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(address indexed staker);\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0xC39A6A754b4937Da3FdC62a19704EB79FA2A0C5c","bytecode":"0x60806040523480156200001157600080fd5b5060405162002909380380620029098339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b6126f280620002176000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063de18a50811610066578063de18a5081461025f578063ef6fd8781461028f578063f2fde38b146102bf578063ffa2e953146102db576100ea565b80638da5cb5b146101df578063b3fe5cf2146101fd578063bd4986a01461022f576100ea565b8063583cb30a116100c8578063583cb30a1461016b5780636edad78714610187578063715018a6146101a35780637bd3e3f6146101ad576100ea565b806301c6d035146100ef578063176354fd1461011f57806325c836f91461013b575b600080fd5b6101096004803603810190610104919061170f565b6102f9565b6040516101169190611757565b60405180910390f35b610139600480360381019061013491906117d0565b61046e565b005b6101556004803603810190610150919061170f565b6104f1565b60405161016291906118fb565b60405180910390f35b61018560048036038101906101809190611a52565b610610565b005b6101a1600480360381019061019c9190611a52565b610e20565b005b6101ab610f8d565b005b6101c760048036038101906101c2919061170f565b610fa1565b6040516101d693929190611b3d565b60405180910390f35b6101e7611073565b6040516101f49190611b7b565b60405180910390f35b6102176004803603810190610212919061170f565b61109c565b60405161022693929190611b96565b60405180910390f35b6102496004803603810190610244919061170f565b6111c2565b6040516102569190611b7b565b60405180910390f35b610279600480360381019061027491906117d0565b6112bd565b6040516102869190611bd4565b60405180910390f35b6102a960048036038101906102a4919061170f565b6112d5565b6040516102b69190611bef565b60405180910390f35b6102d960048036038101906102d491906117d0565b61137d565b005b6102e3611400565b6040516102f09190611c70565b60405180910390f35b6000806002600084815260200190815260200160002060405180606001604052908160008201805461032a90611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461035690611cba565b80156103a35780601f10610378576101008083540402835291602001916103a3565b820191906000526020600020905b81548152906001019060200180831161038657829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050905060008160000151511415801561042957506000816040015114155b80156104665750600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614155b915050919050565b610476611426565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc7ff7959ecbc7f4d8d4a9e6afe9dff66f0e84d0707ee870524fe965872ab6e50816040516104e69190611b7b565b60405180910390a150565b6104f961168e565b6002600083815260200190815260200160002060405180606001604052908160008201805461052790611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461055390611cba565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820154815250509050919050565b600082905060008173ffffffffffffffffffffffffffffffffffffffff16635081f66f336040518263ffffffff1660e01b81526004016106509190611b7b565b602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611d00565b90508173ffffffffffffffffffffffffffffffffffffffff166340550a1c826040518263ffffffff1660e01b81526004016106cc9190611b7b565b602060405180830381865afa1580156106e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070d9190611d59565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074390611e09565b60405180910390fd5b6003600087815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490611e9b565b60405180910390fd5b600060036000888152602001908152602001600020600301540361098257848051906020012060001c8614610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90611f2d565b60405180910390fd5b8460036000888152602001908152602001600020600001600001908161087d91906120ef565b50836003600088815260200190815260200160002060000160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260036000888152602001908152602001600020600001600201819055508173ffffffffffffffffffffffffffffffffffffffff1663dd21d6266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096391906121d6565b6003600088815260200190815260200160002060040181905550610b2c565b6003600087815260200190815260200160002060000160000180546109a690611cba565b905085511480156109ea5750600360008781526020019081526020016000206000016000016040516109d89190612291565b60405180910390208580519060200120145b610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a209061231a565b60405180910390fd5b6003600087815260200190815260200160002060000160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790612386565b60405180910390fd5b60036000878152602001908152602001600020600001600201548314610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b22906123f2565b60405180910390fd5b5b60016003600088815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600360008781526020019081526020016000206003016000815480929190610bbf90612441565b91905055503373ffffffffffffffffffffffffffffffffffffffff16867f55a9294995c030f731a7eefced80c512d4bb6826c506f230021a7320ccc1d172878787604051610c0f93929190611b3d565b60405180910390a360036000878152602001908152602001600020600401546003600088815260200190815260200160002060030154118015610c585750610c56866102f9565b155b15610e185784600260008881526020019081526020016000206000019081610c8091906120ef565b50836002600088815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260008881526020019081526020016000206002018190555060028303610d4c576000610d04876111c2565b905086600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c87856040518363ffffffff1660e01b8152600401610da9929190612489565b600060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b50505050857f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38868686604051610e0f93929190611b3d565b60405180910390a25b505050505050565b610e28611426565b82600260008681526020019081526020016000206000019081610e4b91906120ef565b50816002600086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806002600086815260200190815260200160002060020181905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c85836040518363ffffffff1660e01b8152600401610f19929190612489565b600060405180830381600087803b158015610f3357600080fd5b505af1158015610f47573d6000803e3d6000fd5b50505050837f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38848484604051610f7f93929190611b3d565b60405180910390a250505050565b610f95611426565b610f9f60006114a4565b565b6002602052806000526040600020600091509050806000018054610fc490611cba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff090611cba565b801561103d5780601f106110125761010080835404028352916020019161103d565b820191906000526020600020905b81548152906001019060200180831161102057829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052806000526040600020600091509050806000016040518060600160405290816000820180546110cf90611cba565b80601f01602080910402602001604051908101604052809291908181526020018280546110fb90611cba565b80156111485780601f1061111d57610100808354040283529160200191611148565b820191906000526020600020905b81548152906001019060200180831161112b57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050908060030154908060040154905083565b6000600280600084815260200190815260200160002060020154146111ea57600090506112b8565b60006112a16001604060026000878152602001908152602001600020600001805461121490611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461124090611cba565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b50505050506115689092919063ffffffff16565b90506000818051906020012090508060001c925050505b919050565b60046020528060005260406000206000915090505481565b60606002600083815260200190815260200160002060000180546112f890611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461132490611cba565b80156113715780601f1061134657610100808354040283529160200191611371565b820191906000526020600020905b81548152906001019060200180831161135457829003601f168201915b50505050509050919050565b611385611426565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612524565b60405180910390fd5b6113fd816114a4565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61142e611686565b73ffffffffffffffffffffffffffffffffffffffff1661144c611073565b73ffffffffffffffffffffffffffffffffffffffff16146114a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149990612590565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606081601f8361157891906125b0565b10156115b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b090612630565b60405180910390fd5b81836115c591906125b0565b84511015611608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ff9061269c565b60405180910390fd5b6060821560008114611629576040519150600082526020820160405261167a565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611667578051835260208301925060208101905061164a565b50868552601f19601f8301166040525050505b50809150509392505050565b600033905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6116ec816116d9565b81146116f757600080fd5b50565b600081359050611709816116e3565b92915050565b600060208284031215611725576117246116cf565b5b6000611733848285016116fa565b91505092915050565b60008115159050919050565b6117518161173c565b82525050565b600060208201905061176c6000830184611748565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061179d82611772565b9050919050565b6117ad81611792565b81146117b857600080fd5b50565b6000813590506117ca816117a4565b92915050565b6000602082840312156117e6576117e56116cf565b5b60006117f4848285016117bb565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561183757808201518184015260208101905061181c565b60008484015250505050565b6000601f19601f8301169050919050565b600061185f826117fd565b6118698185611808565b9350611879818560208601611819565b61188281611843565b840191505092915050565b61189681611792565b82525050565b6118a5816116d9565b82525050565b600060608301600083015184820360008601526118c88282611854565b91505060208301516118dd602086018261188d565b5060408301516118f0604086018261189c565b508091505092915050565b6000602082019050818103600083015261191581846118ab565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61195f82611843565b810181811067ffffffffffffffff8211171561197e5761197d611927565b5b80604052505050565b60006119916116c5565b905061199d8282611956565b919050565b600067ffffffffffffffff8211156119bd576119bc611927565b5b6119c682611843565b9050602081019050919050565b82818337600083830152505050565b60006119f56119f0846119a2565b611987565b905082815260208101848484011115611a1157611a10611922565b5b611a1c8482856119d3565b509392505050565b600082601f830112611a3957611a3861191d565b5b8135611a498482602086016119e2565b91505092915050565b60008060008060808587031215611a6c57611a6b6116cf565b5b6000611a7a878288016116fa565b945050602085013567ffffffffffffffff811115611a9b57611a9a6116d4565b5b611aa787828801611a24565b9350506040611ab8878288016117bb565b9250506060611ac9878288016116fa565b91505092959194509250565b600082825260208201905092915050565b6000611af1826117fd565b611afb8185611ad5565b9350611b0b818560208601611819565b611b1481611843565b840191505092915050565b611b2881611792565b82525050565b611b37816116d9565b82525050565b60006060820190508181036000830152611b578186611ae6565b9050611b666020830185611b1f565b611b736040830184611b2e565b949350505050565b6000602082019050611b906000830184611b1f565b92915050565b60006060820190508181036000830152611bb081866118ab565b9050611bbf6020830185611b2e565b611bcc6040830184611b2e565b949350505050565b6000602082019050611be96000830184611b2e565b92915050565b60006020820190508181036000830152611c098184611ae6565b905092915050565b6000819050919050565b6000611c36611c31611c2c84611772565b611c11565b611772565b9050919050565b6000611c4882611c1b565b9050919050565b6000611c5a82611c3d565b9050919050565b611c6a81611c4f565b82525050565b6000602082019050611c856000830184611c61565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611cd257607f821691505b602082108103611ce557611ce4611c8b565b5b50919050565b600081519050611cfa816117a4565b92915050565b600060208284031215611d1657611d156116cf565b5b6000611d2484828501611ceb565b91505092915050565b611d368161173c565b8114611d4157600080fd5b50565b600081519050611d5381611d2d565b92915050565b600060208284031215611d6f57611d6e6116cf565b5b6000611d7d84828501611d44565b91505092915050565b600082825260208201905092915050565b7f4f6e6c79206163746976652076616c696461746f72732063616e20736574207260008201527f6f7574696e672064617461000000000000000000000000000000000000000000602082015250565b6000611df3602b83611d86565b9150611dfe82611d97565b604082019050919050565b60006020820190508181036000830152611e2281611de6565b9050919050565b7f596f75206861766520616c726561647920766f74656420666f7220746869732060008201527f6b65790000000000000000000000000000000000000000000000000000000000602082015250565b6000611e85602383611d86565b9150611e9082611e29565b604082019050919050565b60006020820190508181036000830152611eb481611e78565b9050919050565b7f746f6b656e496420646f6573206e6f74206d6174636820686173686564206b6560008201527f7950617274730000000000000000000000000000000000000000000000000000602082015250565b6000611f17602683611d86565b9150611f2282611ebb565b604082019050919050565b60006020820190508181036000830152611f4681611f0a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302611faf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611f72565b611fb98683611f72565b95508019841693508086168417925050509392505050565b6000611fec611fe7611fe2846116d9565b611c11565b6116d9565b9050919050565b6000819050919050565b61200683611fd1565b61201a61201282611ff3565b848454611f7f565b825550505050565b600090565b61202f612022565b61203a818484611ffd565b505050565b5b8181101561205e57612053600082612027565b600181019050612040565b5050565b601f8211156120a35761207481611f4d565b61207d84611f62565b8101602085101561208c578190505b6120a061209885611f62565b83018261203f565b50505b505050565b600082821c905092915050565b60006120c6600019846008026120a8565b1980831691505092915050565b60006120df83836120b5565b9150826002028217905092915050565b6120f8826117fd565b67ffffffffffffffff81111561211157612110611927565b5b61211b8254611cba565b612126828285612062565b600060209050601f8311600181146121595760008415612147578287015190505b61215185826120d3565b8655506121b9565b601f19841661216786611f4d565b60005b8281101561218f5784890151825560018201915060208501945060208101905061216a565b868310156121ac57848901516121a8601f8916826120b5565b8355505b6001600288020188555050505b505050505050565b6000815190506121d0816116e3565b92915050565b6000602082840312156121ec576121eb6116cf565b5b60006121fa848285016121c1565b91505092915050565b600081905092915050565b6000815461221b81611cba565b6122258186612203565b94506001821660008114612240576001811461225557612288565b60ff1983168652811515820286019350612288565b61225e85611f4d565b60005b8381101561228057815481890152600182019150602081019050612261565b838801955050505b50505092915050565b600061229d828461220e565b915081905092915050565b7f7075626b657920646f6573206e6f74206d617463682070726576696f7573207260008201527f6567697374726174696f6e730000000000000000000000000000000000000000602082015250565b6000612304602c83611d86565b915061230f826122a8565b604082019050919050565b60006020820190508181036000830152612333816122f7565b9050919050565b7f7374616b696e67436f6e747261637420646f6573206e6f74206d617463680000600082015250565b6000612370601e83611d86565b915061237b8261233a565b602082019050919050565b6000602082019050818103600083015261239f81612363565b9050919050565b7f6b65795479706520646f6573206e6f74206d6174636800000000000000000000600082015250565b60006123dc601683611d86565b91506123e7826123a6565b602082019050919050565b6000602082019050818103600083015261240b816123cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061244c826116d9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361247e5761247d612412565b5b600182019050919050565b600060408201905061249e6000830185611b2e565b6124ab6020830184611b2e565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061250e602683611d86565b9150612519826124b2565b604082019050919050565b6000602082019050818103600083015261253d81612501565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061257a602083611d86565b915061258582612544565b602082019050919050565b600060208201905081810360008301526125a98161256d565b9050919050565b60006125bb826116d9565b91506125c6836116d9565b92508282019050808211156125de576125dd612412565b5b92915050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061261a600e83611d86565b9150612625826125e4565b602082019050919050565b600060208201905081810360008301526126498161260d565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b6000612686601183611d86565b915061269182612650565b602082019050919050565b600060208201905081810360008301526126b581612679565b905091905056fea2646970667358221220f0893e895610532b4eae108c366bb96b0bf6f3521b3ca536e8d0934601d8a40e64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063de18a50811610066578063de18a5081461025f578063ef6fd8781461028f578063f2fde38b146102bf578063ffa2e953146102db576100ea565b80638da5cb5b146101df578063b3fe5cf2146101fd578063bd4986a01461022f576100ea565b8063583cb30a116100c8578063583cb30a1461016b5780636edad78714610187578063715018a6146101a35780637bd3e3f6146101ad576100ea565b806301c6d035146100ef578063176354fd1461011f57806325c836f91461013b575b600080fd5b6101096004803603810190610104919061170f565b6102f9565b6040516101169190611757565b60405180910390f35b610139600480360381019061013491906117d0565b61046e565b005b6101556004803603810190610150919061170f565b6104f1565b60405161016291906118fb565b60405180910390f35b61018560048036038101906101809190611a52565b610610565b005b6101a1600480360381019061019c9190611a52565b610e20565b005b6101ab610f8d565b005b6101c760048036038101906101c2919061170f565b610fa1565b6040516101d693929190611b3d565b60405180910390f35b6101e7611073565b6040516101f49190611b7b565b60405180910390f35b6102176004803603810190610212919061170f565b61109c565b60405161022693929190611b96565b60405180910390f35b6102496004803603810190610244919061170f565b6111c2565b6040516102569190611b7b565b60405180910390f35b610279600480360381019061027491906117d0565b6112bd565b6040516102869190611bd4565b60405180910390f35b6102a960048036038101906102a4919061170f565b6112d5565b6040516102b69190611bef565b60405180910390f35b6102d960048036038101906102d491906117d0565b61137d565b005b6102e3611400565b6040516102f09190611c70565b60405180910390f35b6000806002600084815260200190815260200160002060405180606001604052908160008201805461032a90611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461035690611cba565b80156103a35780601f10610378576101008083540402835291602001916103a3565b820191906000526020600020905b81548152906001019060200180831161038657829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050905060008160000151511415801561042957506000816040015114155b80156104665750600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614155b915050919050565b610476611426565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc7ff7959ecbc7f4d8d4a9e6afe9dff66f0e84d0707ee870524fe965872ab6e50816040516104e69190611b7b565b60405180910390a150565b6104f961168e565b6002600083815260200190815260200160002060405180606001604052908160008201805461052790611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461055390611cba565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820154815250509050919050565b600082905060008173ffffffffffffffffffffffffffffffffffffffff16635081f66f336040518263ffffffff1660e01b81526004016106509190611b7b565b602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611d00565b90508173ffffffffffffffffffffffffffffffffffffffff166340550a1c826040518263ffffffff1660e01b81526004016106cc9190611b7b565b602060405180830381865afa1580156106e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070d9190611d59565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074390611e09565b60405180910390fd5b6003600087815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490611e9b565b60405180910390fd5b600060036000888152602001908152602001600020600301540361098257848051906020012060001c8614610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90611f2d565b60405180910390fd5b8460036000888152602001908152602001600020600001600001908161087d91906120ef565b50836003600088815260200190815260200160002060000160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260036000888152602001908152602001600020600001600201819055508173ffffffffffffffffffffffffffffffffffffffff1663dd21d6266040518163ffffffff1660e01b8152600401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096391906121d6565b6003600088815260200190815260200160002060040181905550610b2c565b6003600087815260200190815260200160002060000160000180546109a690611cba565b905085511480156109ea5750600360008781526020019081526020016000206000016000016040516109d89190612291565b60405180910390208580519060200120145b610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a209061231a565b60405180910390fd5b6003600087815260200190815260200160002060000160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ad0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac790612386565b60405180910390fd5b60036000878152602001908152602001600020600001600201548314610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b22906123f2565b60405180910390fd5b5b60016003600088815260200190815260200160002060050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600360008781526020019081526020016000206003016000815480929190610bbf90612441565b91905055503373ffffffffffffffffffffffffffffffffffffffff16867f55a9294995c030f731a7eefced80c512d4bb6826c506f230021a7320ccc1d172878787604051610c0f93929190611b3d565b60405180910390a360036000878152602001908152602001600020600401546003600088815260200190815260200160002060030154118015610c585750610c56866102f9565b155b15610e185784600260008881526020019081526020016000206000019081610c8091906120ef565b50836002600088815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260008881526020019081526020016000206002018190555060028303610d4c576000610d04876111c2565b905086600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c87856040518363ffffffff1660e01b8152600401610da9929190612489565b600060405180830381600087803b158015610dc357600080fd5b505af1158015610dd7573d6000803e3d6000fd5b50505050857f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38868686604051610e0f93929190611b3d565b60405180910390a25b505050505050565b610e28611426565b82600260008681526020019081526020016000206000019081610e4b91906120ef565b50816002600086815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806002600086815260200190815260200160002060020181905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c110a9c85836040518363ffffffff1660e01b8152600401610f19929190612489565b600060405180830381600087803b158015610f3357600080fd5b505af1158015610f47573d6000803e3d6000fd5b50505050837f5c4ca40b0470d7d59d8b59dfbd57d9a2e50a8f0b84d22521c146b646274e1a38848484604051610f7f93929190611b3d565b60405180910390a250505050565b610f95611426565b610f9f60006114a4565b565b6002602052806000526040600020600091509050806000018054610fc490611cba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ff090611cba565b801561103d5780601f106110125761010080835404028352916020019161103d565b820191906000526020600020905b81548152906001019060200180831161102057829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905083565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052806000526040600020600091509050806000016040518060600160405290816000820180546110cf90611cba565b80601f01602080910402602001604051908101604052809291908181526020018280546110fb90611cba565b80156111485780601f1061111d57610100808354040283529160200191611148565b820191906000526020600020905b81548152906001019060200180831161112b57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481525050908060030154908060040154905083565b6000600280600084815260200190815260200160002060020154146111ea57600090506112b8565b60006112a16001604060026000878152602001908152602001600020600001805461121490611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461124090611cba565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b50505050506115689092919063ffffffff16565b90506000818051906020012090508060001c925050505b919050565b60046020528060005260406000206000915090505481565b60606002600083815260200190815260200160002060000180546112f890611cba565b80601f016020809104026020016040519081016040528092919081815260200182805461132490611cba565b80156113715780601f1061134657610100808354040283529160200191611371565b820191906000526020600020905b81548152906001019060200180831161135457829003601f168201915b50505050509050919050565b611385611426565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113eb90612524565b60405180910390fd5b6113fd816114a4565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61142e611686565b73ffffffffffffffffffffffffffffffffffffffff1661144c611073565b73ffffffffffffffffffffffffffffffffffffffff16146114a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149990612590565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606081601f8361157891906125b0565b10156115b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b090612630565b60405180910390fd5b81836115c591906125b0565b84511015611608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ff9061269c565b60405180910390fd5b6060821560008114611629576040519150600082526020820160405261167a565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015611667578051835260208301925060208101905061164a565b50868552601f19601f8301166040525050505b50809150509392505050565b600033905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6116ec816116d9565b81146116f757600080fd5b50565b600081359050611709816116e3565b92915050565b600060208284031215611725576117246116cf565b5b6000611733848285016116fa565b91505092915050565b60008115159050919050565b6117518161173c565b82525050565b600060208201905061176c6000830184611748565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061179d82611772565b9050919050565b6117ad81611792565b81146117b857600080fd5b50565b6000813590506117ca816117a4565b92915050565b6000602082840312156117e6576117e56116cf565b5b60006117f4848285016117bb565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561183757808201518184015260208101905061181c565b60008484015250505050565b6000601f19601f8301169050919050565b600061185f826117fd565b6118698185611808565b9350611879818560208601611819565b61188281611843565b840191505092915050565b61189681611792565b82525050565b6118a5816116d9565b82525050565b600060608301600083015184820360008601526118c88282611854565b91505060208301516118dd602086018261188d565b5060408301516118f0604086018261189c565b508091505092915050565b6000602082019050818103600083015261191581846118ab565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61195f82611843565b810181811067ffffffffffffffff8211171561197e5761197d611927565b5b80604052505050565b60006119916116c5565b905061199d8282611956565b919050565b600067ffffffffffffffff8211156119bd576119bc611927565b5b6119c682611843565b9050602081019050919050565b82818337600083830152505050565b60006119f56119f0846119a2565b611987565b905082815260208101848484011115611a1157611a10611922565b5b611a1c8482856119d3565b509392505050565b600082601f830112611a3957611a3861191d565b5b8135611a498482602086016119e2565b91505092915050565b60008060008060808587031215611a6c57611a6b6116cf565b5b6000611a7a878288016116fa565b945050602085013567ffffffffffffffff811115611a9b57611a9a6116d4565b5b611aa787828801611a24565b9350506040611ab8878288016117bb565b9250506060611ac9878288016116fa565b91505092959194509250565b600082825260208201905092915050565b6000611af1826117fd565b611afb8185611ad5565b9350611b0b818560208601611819565b611b1481611843565b840191505092915050565b611b2881611792565b82525050565b611b37816116d9565b82525050565b60006060820190508181036000830152611b578186611ae6565b9050611b666020830185611b1f565b611b736040830184611b2e565b949350505050565b6000602082019050611b906000830184611b1f565b92915050565b60006060820190508181036000830152611bb081866118ab565b9050611bbf6020830185611b2e565b611bcc6040830184611b2e565b949350505050565b6000602082019050611be96000830184611b2e565b92915050565b60006020820190508181036000830152611c098184611ae6565b905092915050565b6000819050919050565b6000611c36611c31611c2c84611772565b611c11565b611772565b9050919050565b6000611c4882611c1b565b9050919050565b6000611c5a82611c3d565b9050919050565b611c6a81611c4f565b82525050565b6000602082019050611c856000830184611c61565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611cd257607f821691505b602082108103611ce557611ce4611c8b565b5b50919050565b600081519050611cfa816117a4565b92915050565b600060208284031215611d1657611d156116cf565b5b6000611d2484828501611ceb565b91505092915050565b611d368161173c565b8114611d4157600080fd5b50565b600081519050611d5381611d2d565b92915050565b600060208284031215611d6f57611d6e6116cf565b5b6000611d7d84828501611d44565b91505092915050565b600082825260208201905092915050565b7f4f6e6c79206163746976652076616c696461746f72732063616e20736574207260008201527f6f7574696e672064617461000000000000000000000000000000000000000000602082015250565b6000611df3602b83611d86565b9150611dfe82611d97565b604082019050919050565b60006020820190508181036000830152611e2281611de6565b9050919050565b7f596f75206861766520616c726561647920766f74656420666f7220746869732060008201527f6b65790000000000000000000000000000000000000000000000000000000000602082015250565b6000611e85602383611d86565b9150611e9082611e29565b604082019050919050565b60006020820190508181036000830152611eb481611e78565b9050919050565b7f746f6b656e496420646f6573206e6f74206d6174636820686173686564206b6560008201527f7950617274730000000000000000000000000000000000000000000000000000602082015250565b6000611f17602683611d86565b9150611f2282611ebb565b604082019050919050565b60006020820190508181036000830152611f4681611f0a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302611faf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611f72565b611fb98683611f72565b95508019841693508086168417925050509392505050565b6000611fec611fe7611fe2846116d9565b611c11565b6116d9565b9050919050565b6000819050919050565b61200683611fd1565b61201a61201282611ff3565b848454611f7f565b825550505050565b600090565b61202f612022565b61203a818484611ffd565b505050565b5b8181101561205e57612053600082612027565b600181019050612040565b5050565b601f8211156120a35761207481611f4d565b61207d84611f62565b8101602085101561208c578190505b6120a061209885611f62565b83018261203f565b50505b505050565b600082821c905092915050565b60006120c6600019846008026120a8565b1980831691505092915050565b60006120df83836120b5565b9150826002028217905092915050565b6120f8826117fd565b67ffffffffffffffff81111561211157612110611927565b5b61211b8254611cba565b612126828285612062565b600060209050601f8311600181146121595760008415612147578287015190505b61215185826120d3565b8655506121b9565b601f19841661216786611f4d565b60005b8281101561218f5784890151825560018201915060208501945060208101905061216a565b868310156121ac57848901516121a8601f8916826120b5565b8355505b6001600288020188555050505b505050505050565b6000815190506121d0816116e3565b92915050565b6000602082840312156121ec576121eb6116cf565b5b60006121fa848285016121c1565b91505092915050565b600081905092915050565b6000815461221b81611cba565b6122258186612203565b94506001821660008114612240576001811461225557612288565b60ff1983168652811515820286019350612288565b61225e85611f4d565b60005b8381101561228057815481890152600182019150602081019050612261565b838801955050505b50505092915050565b600061229d828461220e565b915081905092915050565b7f7075626b657920646f6573206e6f74206d617463682070726576696f7573207260008201527f6567697374726174696f6e730000000000000000000000000000000000000000602082015250565b6000612304602c83611d86565b915061230f826122a8565b604082019050919050565b60006020820190508181036000830152612333816122f7565b9050919050565b7f7374616b696e67436f6e747261637420646f6573206e6f74206d617463680000600082015250565b6000612370601e83611d86565b915061237b8261233a565b602082019050919050565b6000602082019050818103600083015261239f81612363565b9050919050565b7f6b65795479706520646f6573206e6f74206d6174636800000000000000000000600082015250565b60006123dc601683611d86565b91506123e7826123a6565b602082019050919050565b6000602082019050818103600083015261240b816123cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061244c826116d9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361247e5761247d612412565b5b600182019050919050565b600060408201905061249e6000830185611b2e565b6124ab6020830184611b2e565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061250e602683611d86565b9150612519826124b2565b604082019050919050565b6000602082019050818103600083015261253d81612501565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061257a602083611d86565b915061258582612544565b602082019050919050565b600060208201905081810360008301526125a98161256d565b9050919050565b60006125bb826116d9565b91506125c6836116d9565b92508282019050808211156125de576125dd612412565b5b92915050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061261a600e83611d86565b9150612625826125e4565b602082019050919050565b600060208201905081810360008301526126498161260d565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b6000612686601183611d86565b915061269182612650565b602082019050919050565b600060208201905081810360008301526126b581612679565b905091905056fea2646970667358221220f0893e895610532b4eae108c366bb96b0bf6f3521b3ca536e8d0934601d8a40e64736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"PkpNftAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"pubkey","type":"bytes"},{"indexed":false,"internalType":"address","name":"stakingContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PubkeyRoutingDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"pubkey","type":"bytes"},{"indexed":false,"internalType":"address","name":"stakingContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PubkeyRoutingDataVote","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRoutingData","outputs":[{"components":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"internalType":"struct PubkeyRouter.PubkeyRoutingData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isRouted","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeyRegistrations","outputs":[{"components":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"internalType":"struct PubkeyRouter.PubkeyRoutingData","name":"routingData","type":"tuple"},{"internalType":"uint256","name":"nodeVoteCount","type":"uint256"},{"internalType":"uint256","name":"nodeVoteThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"setRoutingData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"voteForRoutingData","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/RateLimitNFT.json b/deployments/mumbai_80001/RateLimitNFT.json deleted file mode 100644 index b559d64..0000000 --- a/deployments/mumbai_80001/RateLimitNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/RateLimitNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Rate Limit NFT\\n///\\n/// @dev This is the contract for the Rate Limit NFTs\\n/// So the general idea here is that you can mint one of these NFTs to pay for service on Lit\\n/// And how it works, is that you can buy X requestsPerKilosecond over a period of time\\n/// 1 requestsPerKilosecond = 0.001 requests per second and\\n/// 1000 requestsPerKilosecond = 1 request per second\\ncontract RateLimitNFT is\\n ERC721(\\\"Rate Limit Increases on Lit Protocol\\\", \\\"RLI\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using Strings for uint256;\\n /* ========== STATE VARIABLES ========== */\\n\\n address public freeMintSigner;\\n uint256 public additionalRequestsPerKilosecondCost;\\n uint256 public tokenIdCounter;\\n uint256 public defaultRateLimitWindowSeconds = 60 * 60; // 60 mins\\n uint256 public RLIHolderRateLimitWindowSeconds = 5 * 60; // 5 mins\\n uint256 public freeRequestsPerRateLimitWindow = 10;\\n\\n mapping(uint256 => RateLimit) public capacity;\\n mapping(bytes32 => bool) public redeemedFreeMints;\\n\\n struct RateLimit {\\n uint256 requestsPerKilosecond;\\n uint256 expiresAt;\\n }\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n additionalRequestsPerKilosecondCost = 1000000; // 1,000,000 wei\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n // make sure the msgHash matches the tokenId\\n // if these don't match, the user could use any old signature\\n // to mint any number of PKPs\\n // and this would be vulnerable to replay attacks\\n // FIXME this needs the whole \\\"ethereum signed message: \\\\27\\\" thingy prepended to actually work\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(expiresAt, requestsPerKilosecond))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the expiresAt + requestsPerKilosecond. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // make sure it hasn't already been redeemed\\n require(\\n !redeemedFreeMints[msgHash],\\n \\\"This freeMint has already been redeemed. How embarassing.\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function calculateCost(\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n require(\\n requestsPerKilosecond > 0,\\n \\\"The requestsPerKilosecond must be greater than 0\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n\\n // calculate the cost\\n uint256 cost = (requestsPerKilosecond *\\n durationInSeconds *\\n additionalRequestsPerKilosecondCost) / 1000; // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return cost;\\n }\\n\\n function calculateRequestsPerKilosecond(\\n uint256 payingAmount,\\n uint256 expiresAt\\n ) public view returns (uint256) {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInSeconds = (expiresAt - block.timestamp);\\n // console.log(\\\"durationInSeconds: \\\");\\n // console.log(durationInSeconds);\\n\\n // calculate the cost\\n uint256 requestsPerKilosecond = payingAmount /\\n ((durationInSeconds * additionalRequestsPerKilosecondCost) / 1000); // because we used durationInSeconds instead of in Kiloseconds, we need to divide by 1000 at the end to convert back to kiloseconds. This is safe as long as additionalRequestsPerKilosecondCost is greater than 1000\\n\\n return requestsPerKilosecond;\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit Protocol Rate Limit Increase\\\", \\\"description\\\": \\\"This NFT entitles the holder to a rate limit increase on the Lit Protocol Network\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"display_type\\\": \\\"date\\\", \\\"trait_type\\\": \\\"Expiration Date\\\", \\\"value\\\": ',\\n capacity[tokenId].expiresAt.toString(),\\n '}, {\\\"display_type\\\": \\\"number\\\", \\\"trait_type\\\": \\\"Millirequests Per Second\\\", \\\"value\\\": ',\\n capacity[tokenId].requestsPerKilosecond.toString(),\\n \\\"}]}\\\"\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n\\n function isExpired(uint256 tokenId) public view returns (bool) {\\n return capacity[tokenId].expiresAt <= block.timestamp;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function.\\n function mint(uint256 expiresAt) public payable returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n uint256 requestsPerKilosecond = calculateRequestsPerKilosecond(\\n msg.value,\\n expiresAt\\n );\\n\\n // sanity check\\n uint256 cost = calculateCost(requestsPerKilosecond, expiresAt);\\n\\n require(\\n msg.value > 0 && msg.value >= cost,\\n \\\"You must send the cost of this rate limit increase. To check the cost, use the calculateCost function.\\\"\\n );\\n require(cost > 0, \\\"The cost must be greater than 0\\\");\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function freeMint(\\n uint256 expiresAt,\\n uint256 requestsPerKilosecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(expiresAt, requestsPerKilosecond, msgHash, v, r, s);\\n redeemedFreeMints[msgHash] = true;\\n\\n _mintWithoutValueCheck(tokenId, requestsPerKilosecond, expiresAt);\\n\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n uint256 tokenId,\\n uint256 requestsPerKilosecond,\\n uint256 expiresAt\\n ) internal {\\n _safeMint(msg.sender, tokenId);\\n capacity[tokenId] = RateLimit(requestsPerKilosecond, expiresAt);\\n }\\n\\n function setAdditionalRequestsPerKilosecondCost(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n ) public onlyOwner {\\n additionalRequestsPerKilosecondCost = newAdditionalRequestsPerKilosecondCost;\\n emit AdditionalRequestsPerKilosecondCostSet(\\n newAdditionalRequestsPerKilosecondCost\\n );\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n function setRateLimitWindowSeconds(\\n uint256 newRateLimitWindowSeconds\\n ) public onlyOwner {\\n defaultRateLimitWindowSeconds = newRateLimitWindowSeconds;\\n emit RateLimitWindowSecondsSet(newRateLimitWindowSeconds);\\n }\\n\\n function setRLIHolderRateLimitWindowSeconds(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n ) public onlyOwner {\\n RLIHolderRateLimitWindowSeconds = newRLIHolderRateLimitWindowSeconds;\\n emit RLIHolderRateLimitWindowSecondsSet(\\n newRLIHolderRateLimitWindowSeconds\\n );\\n }\\n\\n function setFreeRequestsPerRateLimitWindow(\\n uint256 newFreeRequestsPerRateLimitWindow\\n ) public onlyOwner {\\n freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow;\\n emit FreeRequestsPerRateLimitWindowSet(\\n newFreeRequestsPerRateLimitWindow\\n );\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event AdditionalRequestsPerKilosecondCostSet(\\n uint256 newAdditionalRequestsPerKilosecondCost\\n );\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event RateLimitWindowSecondsSet(uint256 newRateLimitWindowSeconds);\\n event RLIHolderRateLimitWindowSecondsSet(\\n uint256 newRLIHolderRateLimitWindowSeconds\\n );\\n event FreeRequestsPerRateLimitWindowSet(\\n uint256 newFreeRequestsPerRateLimitWindow\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x62FEF0b211a0e42Ef21DBd153Bf91b3cE231824C","bytecode":"0x6080604052610e10600f5561012c601055600a6011553480156200002257600080fd5b50604051806060016040528060248152602001620055f8602491396040518060400160405280600381526020017f524c490000000000000000000000000000000000000000000000000000000000815250816000908162000084919062000419565b50806001908162000096919062000419565b505050620000b9620000ad620000d160201b60201c565b620000d960201b60201c565b6001600b81905550620f4240600d8190555062000500565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200022157607f821691505b602082108103620002375762000236620001d9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000262565b620002ad868362000262565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002fa620002f4620002ee84620002c5565b620002cf565b620002c5565b9050919050565b6000819050919050565b6200031683620002d9565b6200032e620003258262000301565b8484546200026f565b825550505050565b600090565b6200034562000336565b620003528184846200030b565b505050565b5b818110156200037a576200036e6000826200033b565b60018101905062000358565b5050565b601f821115620003c95762000393816200023d565b6200039e8462000252565b81016020851015620003ae578190505b620003c6620003bd8562000252565b83018262000357565b50505b505050565b600082821c905092915050565b6000620003ee60001984600802620003ce565b1980831691505092915050565b6000620004098383620003db565b9150826002028217905092915050565b62000424826200019f565b67ffffffffffffffff81111562000440576200043f620001aa565b5b6200044c825462000208565b620004598282856200037e565b600060209050601f8311600181146200049157600084156200047c578287015190505b620004888582620003fb565b865550620004f8565b601f198416620004a1866200023d565b60005b82811015620004cb57848901518255600182019150602085019450602081019050620004a4565b86831015620004eb5784890151620004e7601f891682620003db565b8355505b6001600288020188555050505b505050505050565b6150e880620005106000396000f3fe6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c6343000811003352617465204c696d697420496e63726561736573206f6e204c69742050726f746f636f6c","deployedBytecode":"0x6080604052600436106102465760003560e01c80634f6ccce711610139578063ab1bbeca116100b6578063ce3946961161007a578063ce394696146108cc578063d9548e5314610909578063e62a219514610946578063e985e9c51461096f578063f2fde38b146109ac578063fb24b22e146109d557610246565b8063ab1bbeca146107c0578063b88d4fde146107fe578063b94a210214610827578063ba45b2ba14610852578063c87b56dd1461088f57610246565b806395d89b41116100fd57806395d89b41146106d457806398bdf6f5146106ff578063995eebab1461072a578063a0712d6814610767578063a22cb4651461079757610246565b80634f6ccce7146105db5780636352211e1461061857806370a0823114610655578063715018a6146106925780638da5cb5b146106a957610246565b80632f745c59116101c75780633ccfd60b1161018b5780633ccfd60b1461051c57806342842e0e1461053357806342966c681461055c5780634659470d146105855780634a5f3acd146105b057610246565b80632f745c59146104275780633488ab131461046457806339f1a4f11461048d5780633b189852146104b65780633b1a72cc146104df57610246565b806318160ddd1161020e57806318160ddd146103425780631f2757131461036d57806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806311fc456214610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190613001565b610a00565b60405161027f9190613049565b60405180910390f35b34801561029457600080fd5b5061029d610b3a565b6040516102aa91906130f4565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d5919061314c565b610bcc565b6040516102e791906131ba565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613201565b610c12565b005b34801561032557600080fd5b50610340600480360381019061033b919061314c565b610d29565b005b34801561034e57600080fd5b50610357610d72565b6040516103649190613250565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f91906132a1565b610d7f565b6040516103a191906132dd565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc91906132f8565b610daf565b005b3480156103df57600080fd5b506103e8610e0f565b6040516103f59190613250565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061314c565b610e15565b005b34801561043357600080fd5b5061044e60048036038101906104499190613201565b610e5e565b60405161045b9190613250565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613384565b610f03565b005b34801561049957600080fd5b506104b460048036038101906104af919061314c565b6110c8565b005b3480156104c257600080fd5b506104dd60048036038101906104d89190613411565b611111565b005b3480156104eb57600080fd5b50610506600480360381019061050191906132a1565b6111a0565b6040516105139190613049565b60405180910390f35b34801561052857600080fd5b506105316111c0565b005b34801561053f57600080fd5b5061055a600480360381019061055591906132f8565b6112d3565b005b34801561056857600080fd5b50610583600480360381019061057e919061314c565b6112f3565b005b34801561059157600080fd5b5061059a61134f565b6040516105a79190613250565b60405180910390f35b3480156105bc57600080fd5b506105c5611355565b6040516105d29190613250565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd919061314c565b61135b565b60405161060f9190613250565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a919061314c565b6113cc565b60405161064c91906131ba565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190613411565b61147d565b6040516106899190613250565b60405180910390f35b34801561069e57600080fd5b506106a7611534565b005b3480156106b557600080fd5b506106be611548565b6040516106cb91906131ba565b60405180910390f35b3480156106e057600080fd5b506106e9611572565b6040516106f691906130f4565b60405180910390f35b34801561070b57600080fd5b50610714611604565b6040516107219190613250565b60405180910390f35b34801561073657600080fd5b50610751600480360381019061074c9190613384565b61160a565b60405161075e9190613250565b60405180910390f35b610781600480360381019061077c919061314c565b61167e565b60405161078e9190613250565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b9919061346a565b611763565b005b3480156107cc57600080fd5b506107e760048036038101906107e2919061314c565b611779565b6040516107f59291906134aa565b60405180910390f35b34801561080a57600080fd5b5061082560048036038101906108209190613608565b61179d565b005b34801561083357600080fd5b5061083c6117ff565b60405161084991906131ba565b60405180910390f35b34801561085e57600080fd5b506108796004803603810190610874919061368b565b611825565b6040516108869190613250565b60405180910390f35b34801561089b57600080fd5b506108b660048036038101906108b1919061314c565b6118ae565b6040516108c391906130f4565b60405180910390f35b3480156108d857600080fd5b506108f360048036038101906108ee919061368b565b611965565b6040516109009190613250565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061314c565b611a31565b60405161093d9190613049565b60405180910390f35b34801561095257600080fd5b5061096d6004803603810190610968919061314c565b611a54565b005b34801561097b57600080fd5b50610996600480360381019061099191906136cb565b611a9d565b6040516109a39190613049565b60405180910390f35b3480156109b857600080fd5b506109d360048036038101906109ce9190613411565b611b31565b005b3480156109e157600080fd5b506109ea611bb4565b6040516109f79190613250565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610acb57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b3357507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b499061373a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b759061373a565b8015610bc25780601f10610b9757610100808354040283529160200191610bc2565b820191906000526020600020905b815481529060010190602001808311610ba557829003601f168201915b5050505050905090565b6000610bd782611bba565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610c1d826113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c84906137dd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610cac611c05565b73ffffffffffffffffffffffffffffffffffffffff161480610cdb5750610cda81610cd5611c05565b611a9d565b5b610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061386f565b60405180910390fd5b610d248383611c0d565b505050565b610d31611cc6565b80600f819055507f8113757de54f756eb308220e3f035727188560fd3230aaf1fbc24e5610fea1f881604051610d679190613250565b60405180910390a150565b6000600980549050905090565b600081604051602001610d929190613907565b604051602081830303815290604052805190602001209050919050565b610dc0610dba611c05565b82611d44565b610dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df69061399f565b60405180910390fd5b610e0a838383611dd9565b505050565b60115481565b610e1d611cc6565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e539190613250565b60405180910390a150565b6000610e698361147d565b8210610eaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea190613a31565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f368787604051602001610f1b929190613a72565b60405160208183030381529060405280519060200120610d7f565b9050848114610f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7190613b36565b60405180910390fd5b600060018686868660405160008152602001604052604051610f9f9493929190613b65565b6020604051602081039080840390855afa158015610fc1573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461105d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105490613c42565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff16156110be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b590613cd4565b60405180910390fd5b5050505050505050565b6110d0611cc6565b806010819055507fad40b1be79d0692234d4fb1d25a47b916b4754dda8187fc0aa1271b7d7adb040816040516111069190613250565b60405180910390a150565b611119611cc6565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b6111c8611cc6565b6002600b540361120d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120490613d40565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161124090613d91565b60006040518083038185875af1925050503d806000811461127d576040519150601f19603f3d011682016040523d82523d6000602084013e611282565b606091505b505090508061129057600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516112bf9190613250565b60405180910390a150506001600b81905550565b6112ee8383836040518060200160405280600081525061179d565b505050565b6113046112fe611c05565b82611d44565b611343576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133a9061399f565b60405180910390fd5b61134c8161203f565b50565b600d5481565b60105481565b6000611365610d72565b82106113a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139d90613e18565b60405180910390fd5b600982815481106113ba576113b9613e38565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146b90613eb3565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e490613f45565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61153c611cc6565b611546600061215c565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115819061373a565b80601f01602080910402602001604051908101604052809291908181526020018280546115ad9061373a565b80156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b5050505050905090565b600e5481565b6000600e600081548092919061161f90613f94565b91905055506000600e549050611639888888888888610f03565b60016013600088815260200190815260200160002060006101000a81548160ff02191690831515021790555061167081888a612222565b809150509695505050505050565b6000600e600081548092919061169390613f94565b91905055506000600e54905060006116ab3485611825565b905060006116b98286611965565b90506000341180156116cb5750803410155b61170a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117019061409a565b60405180910390fd5b6000811161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174490614106565b60405180910390fd5b611758838387612222565b829350505050919050565b61177561176e611c05565b8383612270565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b6117ae6117a8611c05565b83611d44565b6117ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e49061399f565b60405180910390fd5b6117f9848484846123dc565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000428211611869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186090614198565b60405180910390fd5b6000428361187791906141b8565b905060006103e8600d548361188c91906141ec565b611896919061425d565b856118a1919061425d565b9050809250505092915050565b606060006040518061048001604052806104568152602001614c1d61045691399050600061193a826118f56012600088815260200190815260200160002060010154612438565b6119146012600089815260200190815260200160002060000154612438565b6040516020016119269392919061455b565b604051602081830303815290604052612598565b90508060405160200161194d9190614604565b60405160208183030381529060405292505050919050565b60004282116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090614198565b60405180910390fd5b600083116119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e390614698565b60405180910390fd5b600042836119fa91906141b8565b905060006103e8600d548387611a1091906141ec565b611a1a91906141ec565b611a24919061425d565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b611a5c611cc6565b80600d819055507f33e576b8e54523be9c9684e33c7144d859acb615dddc3874462fc0cc73f1ebe381604051611a929190613250565b60405180910390a150565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b39611cc6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9f9061472a565b60405180910390fd5b611bb18161215c565b50565b600f5481565b611bc3816126fb565b611c02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf990613eb3565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c80836113cc565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611cce611c05565b73ffffffffffffffffffffffffffffffffffffffff16611cec611548565b73ffffffffffffffffffffffffffffffffffffffff1614611d42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3990614796565b60405180910390fd5b565b600080611d50836113cc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611d925750611d918185611a9d565b5b80611dd057508373ffffffffffffffffffffffffffffffffffffffff16611db884610bcc565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611df9826113cc565b73ffffffffffffffffffffffffffffffffffffffff1614611e4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4690614828565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb5906148ba565b60405180910390fd5b611ec9838383612767565b611ed4600082611c0d565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f2491906141b8565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7b91906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461203a838383612777565b505050565b600061204a826113cc565b905061205881600084612767565b612063600083611c0d565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120b391906141b8565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461215881600084612777565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61222c338461277c565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d59061495a565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123cf9190613049565b60405180910390a3505050565b6123e7848484611dd9565b6123f38484848461279a565b612432576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612429906149ec565b60405180910390fd5b50505050565b60606000820361247f576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612593565b600082905060005b600082146124b157808061249a90613f94565b915050600a826124aa919061425d565b9150612487565b60008167ffffffffffffffff8111156124cd576124cc6134dd565b5b6040519080825280601f01601f1916602001820160405280156124ff5781602001600182028036833780820191505090505b5090505b6000851461258c5760018261251891906141b8565b9150600a856125279190614a0c565b603061253391906148da565b60f81b81838151811061254957612548613e38565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612585919061425d565b9450612503565b8093505050505b919050565b606060008251036125ba576040518060200160405280600081525090506126f6565b600060405180606001604052806040815260200161507360409139905060006003600285516125e991906148da565b6125f3919061425d565b60046125ff91906141ec565b67ffffffffffffffff811115612618576126176134dd565b5b6040519080825280601f01601f19166020018201604052801561264a5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126b6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061265b565b50506003865106600181146126d257600281146126e5576126ed565b603d6001830353603d60028303536126ed565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b612772838383612921565b505050565b505050565b612796828260405180602001604052806000815250612a33565b5050565b60006127bb8473ffffffffffffffffffffffffffffffffffffffff16612a8e565b15612914578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127e4611c05565b8786866040518563ffffffff1660e01b81526004016128069493929190614a87565b6020604051808303816000875af192505050801561284257506040513d601f19601f8201168201806040525081019061283f9190614ae8565b60015b6128c4573d8060008114612872576040519150601f19603f3d011682016040523d82523d6000602084013e612877565b606091505b5060008151036128bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b3906149ec565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612919565b600190505b949350505050565b61292c838383612ab1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361296e5761296981612ab6565b6129ad565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129ac576129ab8382612aff565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ef576129ea81612c6c565b612a2e565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612a2d57612a2c8282612d3d565b5b5b505050565b612a3d8383612dbc565b612a4a600084848461279a565b612a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a80906149ec565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612b0c8461147d565b612b1691906141b8565b9050600060086000848152602001908152602001600020549050818114612bfb576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612c8091906141b8565b90506000600a6000848152602001908152602001600020549050600060098381548110612cb057612caf613e38565b5b906000526020600020015490508060098381548110612cd257612cd1613e38565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612d2157612d20614b15565b5b6001900381819060005260206000200160009055905550505050565b6000612d488361147d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e2290614b90565b60405180910390fd5b612e34816126fb565b15612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b90614bfc565b60405180910390fd5b612e8060008383612767565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ed091906148da565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f9160008383612777565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fde81612fa9565b8114612fe957600080fd5b50565b600081359050612ffb81612fd5565b92915050565b60006020828403121561301757613016612f9f565b5b600061302584828501612fec565b91505092915050565b60008115159050919050565b6130438161302e565b82525050565b600060208201905061305e600083018461303a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561309e578082015181840152602081019050613083565b60008484015250505050565b6000601f19601f8301169050919050565b60006130c682613064565b6130d0818561306f565b93506130e0818560208601613080565b6130e9816130aa565b840191505092915050565b6000602082019050818103600083015261310e81846130bb565b905092915050565b6000819050919050565b61312981613116565b811461313457600080fd5b50565b60008135905061314681613120565b92915050565b60006020828403121561316257613161612f9f565b5b600061317084828501613137565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131a482613179565b9050919050565b6131b481613199565b82525050565b60006020820190506131cf60008301846131ab565b92915050565b6131de81613199565b81146131e957600080fd5b50565b6000813590506131fb816131d5565b92915050565b6000806040838503121561321857613217612f9f565b5b6000613226858286016131ec565b925050602061323785828601613137565b9150509250929050565b61324a81613116565b82525050565b60006020820190506132656000830184613241565b92915050565b6000819050919050565b61327e8161326b565b811461328957600080fd5b50565b60008135905061329b81613275565b92915050565b6000602082840312156132b7576132b6612f9f565b5b60006132c58482850161328c565b91505092915050565b6132d78161326b565b82525050565b60006020820190506132f260008301846132ce565b92915050565b60008060006060848603121561331157613310612f9f565b5b600061331f868287016131ec565b9350506020613330868287016131ec565b925050604061334186828701613137565b9150509250925092565b600060ff82169050919050565b6133618161334b565b811461336c57600080fd5b50565b60008135905061337e81613358565b92915050565b60008060008060008060c087890312156133a1576133a0612f9f565b5b60006133af89828a01613137565b96505060206133c089828a01613137565b95505060406133d189828a0161328c565b94505060606133e289828a0161336f565b93505060806133f389828a0161328c565b92505060a061340489828a0161328c565b9150509295509295509295565b60006020828403121561342757613426612f9f565b5b6000613435848285016131ec565b91505092915050565b6134478161302e565b811461345257600080fd5b50565b6000813590506134648161343e565b92915050565b6000806040838503121561348157613480612f9f565b5b600061348f858286016131ec565b92505060206134a085828601613455565b9150509250929050565b60006040820190506134bf6000830185613241565b6134cc6020830184613241565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613515826130aa565b810181811067ffffffffffffffff82111715613534576135336134dd565b5b80604052505050565b6000613547612f95565b9050613553828261350c565b919050565b600067ffffffffffffffff821115613573576135726134dd565b5b61357c826130aa565b9050602081019050919050565b82818337600083830152505050565b60006135ab6135a684613558565b61353d565b9050828152602081018484840111156135c7576135c66134d8565b5b6135d2848285613589565b509392505050565b600082601f8301126135ef576135ee6134d3565b5b81356135ff848260208601613598565b91505092915050565b6000806000806080858703121561362257613621612f9f565b5b6000613630878288016131ec565b9450506020613641878288016131ec565b935050604061365287828801613137565b925050606085013567ffffffffffffffff81111561367357613672612fa4565b5b61367f878288016135da565b91505092959194509250565b600080604083850312156136a2576136a1612f9f565b5b60006136b085828601613137565b92505060206136c185828601613137565b9150509250929050565b600080604083850312156136e2576136e1612f9f565b5b60006136f0858286016131ec565b9250506020613701858286016131ec565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061375257607f821691505b6020821081036137655761376461370b565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006137c760218361306f565b91506137d28261376b565b604082019050919050565b600060208201905081810360008301526137f6816137ba565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000613859603e8361306f565b9150613864826137fd565b604082019050919050565b600060208201905081810360008301526138888161384c565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b60006138d0601c8361388f565b91506138db8261389a565b601c82019050919050565b6000819050919050565b6139016138fc8261326b565b6138e6565b82525050565b6000613912826138c3565b915061391e82846138f0565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613989602e8361306f565b91506139948261392d565b604082019050919050565b600060208201905081810360008301526139b88161397c565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613a1b602b8361306f565b9150613a26826139bf565b604082019050919050565b60006020820190508181036000830152613a4a81613a0e565b9050919050565b6000819050919050565b613a6c613a6782613116565b613a51565b82525050565b6000613a7e8285613a5b565b602082019150613a8e8284613a5b565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724b696c6f7365636f60208201527f6e642e20204578706c61696e20796f757273656c662100000000000000000000604082015250565b6000613b2060568361306f565b9150613b2b82613a9e565b606082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b613b5f8161334b565b82525050565b6000608082019050613b7a60008301876132ce565b613b876020830186613b56565b613b9460408301856132ce565b613ba160608301846132ce565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613c2c60418361306f565b9150613c3782613baa565b606082019050919050565b60006020820190508181036000830152613c5b81613c1f565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613cbe603a8361306f565b9150613cc982613c62565b604082019050919050565b60006020820190508181036000830152613ced81613cb1565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613d2a601f8361306f565b9150613d3582613cf4565b602082019050919050565b60006020820190508181036000830152613d5981613d1d565b9050919050565b600081905092915050565b50565b6000613d7b600083613d60565b9150613d8682613d6b565b600082019050919050565b6000613d9c82613d6e565b9150819050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613e02602c8361306f565b9150613e0d82613da6565b604082019050919050565b60006020820190508181036000830152613e3181613df5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613e9d60188361306f565b9150613ea882613e67565b602082019050919050565b60006020820190508181036000830152613ecc81613e90565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613f2f60298361306f565b9150613f3a82613ed3565b604082019050919050565b60006020820190508181036000830152613f5e81613f22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f9f82613116565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd157613fd0613f65565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b600061408460678361306f565b915061408f82613fdc565b608082019050919050565b600060208201905081810360008301526140b381614077565b9050919050565b7f54686520636f7374206d7573742062652067726561746572207468616e203000600082015250565b60006140f0601f8361306f565b91506140fb826140ba565b602082019050919050565b6000602082019050818103600083015261411f816140e3565b9050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061418260238361306f565b915061418d82614126565b604082019050919050565b600060208201905081810360008301526141b181614175565b9050919050565b60006141c382613116565b91506141ce83613116565b92508282039050818111156141e6576141e5613f65565b5b92915050565b60006141f782613116565b915061420283613116565b925082820261421081613116565b9150828204841483151761422757614226613f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061426882613116565b915061427383613116565b9250826142835761428261422e565b5b828204905092915050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061435c60a08361388f565b91506143678261428e565b60a082019050919050565b600081519050919050565b600061438882614372565b6143928185613d60565b93506143a2818560208601613080565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b600061443060548361388f565b915061443b826143ae565b605482019050919050565b600061445182613064565b61445b818561388f565b935061446b818560208601613080565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a20224d696c6c69726571756573747320506572205360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006144f960518361388f565b915061450482614477565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061454560038361388f565b91506145508261450f565b600382019050919050565b60006145668261434f565b9150614572828661437d565b915061457d82614423565b91506145898285614446565b9150614594826144ec565b91506145a08284614446565b91506145ab82614538565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006145ee601d8361388f565b91506145f9826145b8565b601d82019050919050565b600061460f826145e1565b915061461b8284614446565b915081905092915050565b7f5468652072657175657374735065724b696c6f7365636f6e64206d757374206260008201527f652067726561746572207468616e203000000000000000000000000000000000602082015250565b600061468260308361306f565b915061468d82614626565b604082019050919050565b600060208201905081810360008301526146b181614675565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061471460268361306f565b915061471f826146b8565b604082019050919050565b6000602082019050818103600083015261474381614707565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061478060208361306f565b915061478b8261474a565b602082019050919050565b600060208201905081810360008301526147af81614773565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061481260258361306f565b915061481d826147b6565b604082019050919050565b6000602082019050818103600083015261484181614805565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006148a460248361306f565b91506148af82614848565b604082019050919050565b600060208201905081810360008301526148d381614897565b9050919050565b60006148e582613116565b91506148f083613116565b925082820190508082111561490857614907613f65565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061494460198361306f565b915061494f8261490e565b602082019050919050565b6000602082019050818103600083015261497381614937565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006149d660328361306f565b91506149e18261497a565b604082019050919050565b60006020820190508181036000830152614a05816149c9565b9050919050565b6000614a1782613116565b9150614a2283613116565b925082614a3257614a3161422e565b5b828206905092915050565b600082825260208201905092915050565b6000614a5982614372565b614a638185614a3d565b9350614a73818560208601613080565b614a7c816130aa565b840191505092915050565b6000608082019050614a9c60008301876131ab565b614aa960208301866131ab565b614ab66040830185613241565b8181036060830152614ac88184614a4e565b905095945050505050565b600081519050614ae281612fd5565b92915050565b600060208284031215614afe57614afd612f9f565b5b6000614b0c84828501614ad3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614b7a60208361306f565b9150614b8582614b44565b602082019050919050565b60006020820190508181036000830152614ba981614b6d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614be6601c8361306f565b9150614bf182614bb0565b602082019050919050565b60006020820190508181036000830152614c1581614bd9565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ecc801a12a2e0d1a5a908de9b115e4e66d0edb56127ab1ebade4880c38348ab564736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"AdditionalRequestsPerKilosecondCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"FreeRequestsPerRateLimitWindowSet","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":false,"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"RLIHolderRateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"RateLimitWindowSecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"RLIHolderRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalRequestsPerKilosecondCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payingAmount","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateRequestsPerKilosecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capacity","outputs":[{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRateLimitWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerKilosecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeRequestsPerRateLimitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"isExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"redeemedFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAdditionalRequestsPerKilosecondCost","type":"uint256"}],"name":"setAdditionalRequestsPerKilosecondCost","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"setFreeRequestsPerRateLimitWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRLIHolderRateLimitWindowSeconds","type":"uint256"}],"name":"setRLIHolderRateLimitWindowSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRateLimitWindowSeconds","type":"uint256"}],"name":"setRateLimitWindowSeconds","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/SoloNetPKP.json b/deployments/mumbai_80001/SoloNetPKP.json deleted file mode 100644 index 26c26c6..0000000 --- a/deployments/mumbai_80001/SoloNetPKP.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x94AAFa05dFE208E1bdD2bF678DAe464725F1E752","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000559565b508060019081620000a1919062000559565b505050620000c4620000b86200013c60201b60201c565b6200014460201b60201c565b6001600b81905550655af3107a4000600e8190555033600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001353360116200020a60201b6200240d1790919060201c565b5062000640565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006200023a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200024260201b60201c565b905092915050565b6000620002568383620002bc60201b60201c565b620002b1578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050620002b6565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200036157607f821691505b60208210810362000377576200037662000319565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003a2565b620003ed8683620003a2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200043a620004346200042e8462000405565b6200040f565b62000405565b9050919050565b6000819050919050565b620004568362000419565b6200046e620004658262000441565b848454620003af565b825550505050565b600090565b6200048562000476565b620004928184846200044b565b505050565b5b81811015620004ba57620004ae6000826200047b565b60018101905062000498565b5050565b601f8211156200050957620004d3816200037d565b620004de8462000392565b81016020851015620004ee578190505b62000506620004fd8562000392565b83018262000497565b50505b505050565b600082821c905092915050565b60006200052e600019846008026200050e565b1980831691505092915050565b60006200054983836200051b565b9150826002028217905092915050565b6200056482620002df565b67ffffffffffffffff81111562000580576200057f620002ea565b5b6200058c825462000348565b62000599828285620004be565b600060209050601f831160018114620005d15760008415620005bc578287015190505b620005c885826200053b565b86555062000638565b601f198416620005e1866200037d565b60005b828110156200060b57848901518255600182019150602085019450602081019050620005e4565b868310156200062b578489015162000627601f8916826200051b565b8355505b6001600288020188555050505b505050505050565b61598b80620006506000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122053e84d2f07d618df6231b379034020b2d29aac26ccc7878e790313eeaa62361464736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122053e84d2f07d618df6231b379034020b2d29aac26ccc7878e790313eeaa62361464736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterPermitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRevoked","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingAddress","type":"address"}],"name":"StakingAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"_getTokenIdToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"addPermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"removePermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/SoloNetPKPHelper.json b/deployments/mumbai_80001/SoloNetPKPHelper.json deleted file mode 100644 index da33157..0000000 --- a/deployments/mumbai_80001/SoloNetPKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { SoloNetPKP } from \\\"./SoloNetPKP.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/// @title PKP Helper Contract\\n///\\n/// @dev This is the contract that helps minting PKPs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n SoloNetPKP public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = SoloNetPKP(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintAndAddAuthMethods(\\n bytes memory pubkey,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintAndAddAuthMethodsWithTypes(\\n pubkey,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintAndAddAuthMethodsWithTypes(\\n bytes memory pubkey,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpNFT.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = SoloNetPKP(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x0C936Cff73d95156ee7c403B7f8fd787DA1464a4","bytecode":"0x60806040523480156200001157600080fd5b506040516200254d3803806200254d833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b6122df806200026e6000396000f3fe6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220e17401b868434cfc097ea533947dc7c24ebdbbe0065961530fc203f49fe8710564736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220e17401b868434cfc097ea533947dc7c24ebdbbe0065961530fc203f49fe8710564736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract SoloNetPKP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/mumbai_80001/Staking.json b/deployments/mumbai_80001/Staking.json deleted file mode 100644 index 3615043..0000000 --- a/deployments/mumbai_80001/Staking.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 0;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that adds a cap to the supply of tokens.\\n */\\nabstract contract ERC20Capped is ERC20 {\\n uint256 private immutable _cap;\\n\\n /**\\n * @dev Sets the value of the `cap`. This value is immutable, it can only be\\n * set once during construction.\\n */\\n constructor(uint256 cap_) {\\n require(cap_ > 0, \\\"ERC20Capped: cap is 0\\\");\\n _cap = cap_;\\n }\\n\\n /**\\n * @dev Returns the cap on the token's total supply.\\n */\\n function cap() public view virtual returns (uint256) {\\n return _cap;\\n }\\n\\n /**\\n * @dev See {ERC20-_mint}.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n require(ERC20.totalSupply() + amount <= cap(), \\\"ERC20Capped: cap exceeded\\\");\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (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\\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 } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) 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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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 if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\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(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) 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) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\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) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.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 * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\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 constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\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 ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) 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 return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\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(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) 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. It 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 // 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)`.\\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1;\\n uint256 x = a;\\n if (x >> 128 > 0) {\\n x >>= 128;\\n result <<= 64;\\n }\\n if (x >> 64 > 0) {\\n x >>= 64;\\n result <<= 32;\\n }\\n if (x >> 32 > 0) {\\n x >>= 32;\\n result <<= 16;\\n }\\n if (x >> 16 > 0) {\\n x >>= 16;\\n result <<= 8;\\n }\\n if (x >> 8 > 0) {\\n x >>= 8;\\n result <<= 4;\\n }\\n if (x >> 4 > 0) {\\n x >>= 4;\\n result <<= 2;\\n }\\n if (x >> 2 > 0) {\\n result <<= 1;\\n }\\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 uint256 result = sqrt(a);\\n if (rounding == Rounding.Up && result * result < a) {\\n result += 1;\\n }\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n *\\n * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248) {\\n require(value >= type(int248).min && value <= type(int248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n return int248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240) {\\n require(value >= type(int240).min && value <= type(int240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n return int240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232) {\\n require(value >= type(int232).min && value <= type(int232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n return int232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224) {\\n require(value >= type(int224).min && value <= type(int224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return int224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216) {\\n require(value >= type(int216).min && value <= type(int216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n return int216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208) {\\n require(value >= type(int208).min && value <= type(int208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n return int208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200) {\\n require(value >= type(int200).min && value <= type(int200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n return int200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192) {\\n require(value >= type(int192).min && value <= type(int192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n return int192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184) {\\n require(value >= type(int184).min && value <= type(int184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n return int184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176) {\\n require(value >= type(int176).min && value <= type(int176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n return int176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168) {\\n require(value >= type(int168).min && value <= type(int168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n return int168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160) {\\n require(value >= type(int160).min && value <= type(int160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n return int160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152) {\\n require(value >= type(int152).min && value <= type(int152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n return int152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144) {\\n require(value >= type(int144).min && value <= type(int144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n return int144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136) {\\n require(value >= type(int136).min && value <= type(int136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n return int136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120) {\\n require(value >= type(int120).min && value <= type(int120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n return int120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112) {\\n require(value >= type(int112).min && value <= type(int112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n return int112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104) {\\n require(value >= type(int104).min && value <= type(int104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n return int104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96) {\\n require(value >= type(int96).min && value <= type(int96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return int96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88) {\\n require(value >= type(int88).min && value <= type(int88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n return int88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80) {\\n require(value >= type(int80).min && value <= type(int80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n return int80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72) {\\n require(value >= type(int72).min && value <= type(int72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n return int72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56) {\\n require(value >= type(int56).min && value <= type(int56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n return int56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48) {\\n require(value >= type(int48).min && value <= type(int48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n return int48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40) {\\n require(value >= type(int40).min && value <= type(int40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n return int40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n *\\n * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24) {\\n require(value >= type(int24).min && value <= type(int24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n return int24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n *\\n * _Available since v3.0._\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../security/Pausable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n */\\nabstract contract ERC20Pausable is ERC20, Pausable {\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport { ERC20Capped } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol\\\";\\nimport { ERC20Pausable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol\\\";\\nimport { ERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\\\";\\nimport { ERC20Votes } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable,\\n ERC20Capped,\\n ERC20Pausable,\\n ERC20Permit,\\n ERC20Votes\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n /// @dev The identifier of the role which allows accounts to pause the token.\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n constructor(uint256 cap) ERC20Capped(cap) ERC20Permit(\\\"Lit Protocol\\\") {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setupRole(PAUSER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n\\n /**\\n * @dev Pauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_pause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function pause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to pause\\\"\\n );\\n _pause();\\n }\\n\\n /**\\n * @dev Unpauses all token transfers.\\n *\\n * See {ERC20Pausable} and {Pausable-_unpause}.\\n *\\n * Requirements:\\n *\\n * - the caller must have the `PAUSER_ROLE`.\\n */\\n function unpause() public virtual {\\n require(\\n hasRole(PAUSER_ROLE, _msgSender()),\\n \\\"ERC20PresetMinterPauser: must have pauser role to unpause\\\"\\n );\\n _unpause();\\n }\\n\\n /* Overrides */\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Pausable) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._beforeTokenTransfer(from, to, amount);\\n }\\n\\n function _burn(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n\\n function _mint(\\n address account,\\n uint256 amount\\n ) internal virtual override(ERC20, ERC20Votes, ERC20Capped) {\\n super._mint(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x3618C0A6618F498DC4432867bdA538519d8Ed87C","bytecode":"0x60806040526000600160156101000a81548160ff021916908360048111156200002d576200002c6200039f565b5b02179055503480156200003f57600080fd5b506040516200631238038062006312833981810160405281019062000065919062000438565b60016000819055506000600160006101000a81548160ff021916908315150217905550620000a86200009c620002d460201b60201c565b620002dc60201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060a001604052806050815260200160018152602001600143620001119190620004a3565b8152602001600081526020016050815250600360008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506014600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ef91906200051c565b600a620001fd9190620006a2565b62000209919062000722565b600881905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a391906200051c565b600a620002b19190620006a2565b6001620002bf91906200075a565b6009819055506000600b8190555050620007a5565b600033905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040082620003d3565b9050919050565b6200041281620003f3565b81146200041e57600080fd5b50565b600081519050620004328162000407565b92915050565b600060208284031215620004515762000450620003ce565b5b6000620004618482850162000421565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004b0826200046a565b9150620004bd836200046a565b9250828201905080821115620004d857620004d762000474565b5b92915050565b600060ff82169050919050565b620004f681620004de565b81146200050257600080fd5b50565b6000815190506200051681620004eb565b92915050565b600060208284031215620005355762000534620003ce565b5b6000620005458482850162000505565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115620005ad5780860481111562000585576200058462000474565b5b6001851615620005955780820291505b8081029050620005a5856200054e565b945062000565565b94509492505050565b600082620005c857600190506200069b565b81620005d857600090506200069b565b8160018114620005f15760028114620005fc5762000632565b60019150506200069b565b60ff84111562000611576200061062000474565b5b8360020a9150848211156200062b576200062a62000474565b5b506200069b565b5060208310610133831016604e8410600b84101617156200066c5782820a90508381111562000666576200066562000474565b5b6200069b565b6200067b84848460016200055b565b9250905081840481111562000695576200069462000474565b5b81810290505b9392505050565b6000620006af826200046a565b9150620006bc83620004de565b9250620006eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620005b6565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006200072f826200046a565b91506200073c836200046a565b9250826200074f576200074e620006f3565b5b828204905092915050565b600062000767826200046a565b915062000774836200046a565b925082820262000784816200046a565b915082820484148315176200079e576200079d62000474565b5b5092915050565b615b5d80620007b56000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea2646970667358221220cf9b4297a6fa7a56e01514e8dda7fecd648e4df24b49a7d6675da5df30d9b3fb64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea2646970667358221220cf9b4297a6fa7a56e01514e8dda7fecd648e4df24b49a7d6675da5df30d9b3fb64736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"EpochLengthSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"EpochTimeoutSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"KickPenaltyPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"MinimumStakeSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"ReadyForNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"ResolverContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"StakingTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"StateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"TokenRewardPerTokenPerEpochSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBurned","type":"uint256"}],"name":"ValidatorKickedFromNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reporter","type":"address"},{"indexed":true,"internalType":"address","name":"validatorStakerAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"reason","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"VotedToKickValidatorInNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"}],"name":"adminKickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"amountToBurn","type":"uint256"}],"name":"adminSlashValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"advanceEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"epochLength","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"retries","type":"uint256"},{"internalType":"uint256","name":"timeout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValidatorsInCurrentEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorsInNextEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochNumber","type":"uint256"},{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"address","name":"voterStakerAddress","type":"address"}],"name":"getVotingStatusToKickValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isActiveValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReadyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickPenaltyPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"reason","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"kickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nodeAddressToStakerAddress","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":"pauseEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"requestToJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestToLeave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolverContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"setEpochLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"setEpochState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"setEpochTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"setIpPortNodeAddressAndCommunicationPubKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"setKickPenaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"setResolverContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"setStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"setTokenRewardPerTokenPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"shouldKickValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signalReadyForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"stakeAndJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract LITToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Staking.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenRewardPerTokenPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorCountForConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsInNextEpochAreLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votesToKickValidatorsInNextEpoch","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/AccessControlConditions.json b/deployments/rolluptestnet_987/AccessControlConditions.json deleted file mode 100644 index 6abd303..0000000 --- a/deployments/rolluptestnet_987/AccessControlConditions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/AccessControlConditions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract AccessControlConditions is Ownable, ReentrancyGuard {\\n /* ========== STRUCTS ========== */\\n struct StoredCondition {\\n uint256 value;\\n uint256 securityHash;\\n uint256 chainId;\\n bool permanent;\\n address creator;\\n }\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(uint256 => StoredCondition) public storedConditions;\\n address public signer;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n signer = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n function getCondition(uint256 key)\\n external\\n view\\n returns (StoredCondition memory)\\n {\\n return storedConditions[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent\\n ) external nonReentrant {\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n msg.sender\\n );\\n }\\n\\n function storeConditionWithSigner(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) external nonReentrant {\\n require(\\n msg.sender == signer,\\n \\\"Only signer can call storeConditionsWithSigner.\\\"\\n );\\n _storeCondition(\\n key,\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n }\\n\\n function setSigner(address newSigner) public onlyOwner {\\n signer = newSigner;\\n }\\n\\n /* ========== PRIVATE FUNCTIONS ========== */\\n\\n function _storeCondition(\\n uint256 key,\\n uint256 value,\\n uint256 securityHash,\\n uint256 chainId,\\n bool permanent,\\n address creatorAddress\\n ) private {\\n require(key != 0, \\\"Key must not be zero\\\");\\n if (storedConditions[key].creator != address(0)) {\\n // this is an update\\n require(\\n storedConditions[key].creator == creatorAddress,\\n \\\"Only the condition creator can update it\\\"\\n );\\n require(\\n storedConditions[key].permanent == false,\\n \\\"This condition was stored with the Permanent flag and cannot be updated\\\"\\n );\\n require(msg.sender != signer, \\\"Signer cannot update conditions\\\");\\n }\\n storedConditions[key] = StoredCondition(\\n value,\\n securityHash,\\n chainId,\\n permanent,\\n creatorAddress\\n );\\n\\n emit ConditionStored(key, value, chainId, permanent, creatorAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ConditionStored(\\n uint256 indexed key,\\n uint256 value,\\n uint256 chainId,\\n bool permanent,\\n address creator\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xA36802C2d7056e39c9Aa8e6924f922950c37c3aE","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261007a60201b60201c565b61008260201b60201c565b6001808190555033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610146565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61128b806101556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100935760003560e01c80637bf212f8116100665780637bf212f8146100f85780638da5cb5b146101285780639fd040da14610146578063f2fde38b1461017a578063ff27f2df1461019657610093565b8063238ac933146100985780636c19e783146100b6578063715018a6146100d25780637265434f146100dc575b600080fd5b6100a06101b2565b6040516100ad9190610aa4565b60405180910390f35b6100d060048036038101906100cb9190610af0565b6101d8565b005b6100da610224565b005b6100f660048036038101906100f19190610b8b565b610238565b005b610112600480360381019061010d9190610c18565b610332565b60405161011f9190610cda565b60405180910390f35b6101306103ee565b60405161013d9190610aa4565b60405180910390f35b610160600480360381019061015b9190610c18565b610417565b604051610171959493929190610d13565b60405180910390f35b610194600480360381019061018f9190610af0565b61047a565b005b6101b060048036038101906101ab9190610d66565b6104fd565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e0610566565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61022c610566565b61023660006105e4565b565b60026001540361027d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027490610e3e565b60405180910390fd5b6002600181905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161030c90610ed0565b60405180910390fd5b6103238686868686866106a8565b60018081905550505050505050565b61033a610a1c565b600260008381526020019081526020016000206040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016003820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030160009054906101000a900460ff16908060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905085565b610482610566565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890610f62565b60405180910390fd5b6104fa816105e4565b50565b600260015403610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990610e3e565b60405180910390fd5b60026001819055506105588585858585336106a8565b600180819055505050505050565b61056e610a14565b73ffffffffffffffffffffffffffffffffffffffff1661058c6103ee565b73ffffffffffffffffffffffffffffffffffffffff16146105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d990610fce565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600086036106eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e29061103a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108f4578073ffffffffffffffffffffffffffffffffffffffff166002600088815260200190815260200160002060030160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f0906110cc565b60405180910390fd5b600015156002600088815260200190815260200160002060030160009054906101000a900460ff16151514610863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085a90611184565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906111f0565b60405180910390fd5b5b6040518060a0016040528086815260200185815260200184815260200183151581526020018273ffffffffffffffffffffffffffffffffffffffff168152506002600088815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050857ffb2c1b4938e3cf2dc95120a73dce224dfc1108057906403d419bc7a1748f2cd086858585604051610a049493929190611210565b60405180910390a2505050505050565b600033905090565b6040518060a00160405280600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600080fd5b610acd81610a83565b8114610ad857600080fd5b50565b600081359050610aea81610ac4565b92915050565b600060208284031215610b0657610b05610abf565b5b6000610b1484828501610adb565b91505092915050565b6000819050919050565b610b3081610b1d565b8114610b3b57600080fd5b50565b600081359050610b4d81610b27565b92915050565b60008115159050919050565b610b6881610b53565b8114610b7357600080fd5b50565b600081359050610b8581610b5f565b92915050565b60008060008060008060c08789031215610ba857610ba7610abf565b5b6000610bb689828a01610b3e565b9650506020610bc789828a01610b3e565b9550506040610bd889828a01610b3e565b9450506060610be989828a01610b3e565b9350506080610bfa89828a01610b76565b92505060a0610c0b89828a01610adb565b9150509295509295509295565b600060208284031215610c2e57610c2d610abf565b5b6000610c3c84828501610b3e565b91505092915050565b610c4e81610b1d565b82525050565b610c5d81610b53565b82525050565b610c6c81610a83565b82525050565b60a082016000820151610c886000850182610c45565b506020820151610c9b6020850182610c45565b506040820151610cae6040850182610c45565b506060820151610cc16060850182610c54565b506080820151610cd46080850182610c63565b50505050565b600060a082019050610cef6000830184610c72565b92915050565b610cfe81610b1d565b82525050565b610d0d81610b53565b82525050565b600060a082019050610d286000830188610cf5565b610d356020830187610cf5565b610d426040830186610cf5565b610d4f6060830185610d04565b610d5c6080830184610a95565b9695505050505050565b600080600080600060a08688031215610d8257610d81610abf565b5b6000610d9088828901610b3e565b9550506020610da188828901610b3e565b9450506040610db288828901610b3e565b9350506060610dc388828901610b3e565b9250506080610dd488828901610b76565b9150509295509295909350565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000610e28601f83610de1565b9150610e3382610df2565b602082019050919050565b60006020820190508181036000830152610e5781610e1b565b9050919050565b7f4f6e6c79207369676e65722063616e2063616c6c2073746f7265436f6e64697460008201527f696f6e73576974685369676e65722e0000000000000000000000000000000000602082015250565b6000610eba602f83610de1565b9150610ec582610e5e565b604082019050919050565b60006020820190508181036000830152610ee981610ead565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610f4c602683610de1565b9150610f5782610ef0565b604082019050919050565b60006020820190508181036000830152610f7b81610f3f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610fb8602083610de1565b9150610fc382610f82565b602082019050919050565b60006020820190508181036000830152610fe781610fab565b9050919050565b7f4b6579206d757374206e6f74206265207a65726f000000000000000000000000600082015250565b6000611024601483610de1565b915061102f82610fee565b602082019050919050565b6000602082019050818103600083015261105381611017565b9050919050565b7f4f6e6c792074686520636f6e646974696f6e2063726561746f722063616e207560008201527f7064617465206974000000000000000000000000000000000000000000000000602082015250565b60006110b6602883610de1565b91506110c18261105a565b604082019050919050565b600060208201905081810360008301526110e5816110a9565b9050919050565b7f5468697320636f6e646974696f6e207761732073746f7265642077697468207460008201527f6865205065726d616e656e7420666c616720616e642063616e6e6f742062652060208201527f7570646174656400000000000000000000000000000000000000000000000000604082015250565b600061116e604783610de1565b9150611179826110ec565b606082019050919050565b6000602082019050818103600083015261119d81611161565b9050919050565b7f5369676e65722063616e6e6f742075706461746520636f6e646974696f6e7300600082015250565b60006111da601f83610de1565b91506111e5826111a4565b602082019050919050565b60006020820190508181036000830152611209816111cd565b9050919050565b60006080820190506112256000830187610cf5565b6112326020830186610cf5565b61123f6040830185610d04565b61124c6060830184610a95565b9594505050505056fea2646970667358221220f62f2b3b00cfc2a246fcb11f228b3824381f3f3ebabe8b21067eabef920cd66764736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"key","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"permanent","type":"bool"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"ConditionStored","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":[{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getCondition","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"internalType":"struct AccessControlConditions.StoredCondition","name":"","type":"tuple"}],"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":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"}],"name":"storeCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"storeConditionWithSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"storedConditions","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"securityHash","type":"uint256"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"permanent","type":"bool"},{"internalType":"address","name":"creator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/Allowlist.json b/deployments/rolluptestnet_987/Allowlist.json deleted file mode 100644 index e57ee02..0000000 --- a/deployments/rolluptestnet_987/Allowlist.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Allowlist.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Allowlist is Ownable, ReentrancyGuard {\\n /* ========== STATE VARIABLES ========== */\\n\\n mapping(bytes32 => bool) public allowedItems;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function isAllowed(bytes32 key) external view returns (bool) {\\n return allowedItems[key];\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function setAllowed(bytes32 key) external nonReentrant onlyOwner {\\n allowedItems[key] = true;\\n emit ItemAllowed(key);\\n }\\n\\n function setNotAllowed(bytes32 key) external nonReentrant onlyOwner {\\n allowedItems[key] = false;\\n emit ItemNotAllowed(key);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event ItemAllowed(bytes32 indexed key);\\n event ItemNotAllowed(bytes32 indexed key);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xBB06CAAf9B943AC8Fe0Bd07524432a721BFAf7a3","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003960201b60201c565b61004160201b60201c565b60018081905550610105565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610826806101146000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063865815971161005b57806386581597146100ec5780638767d9aa146101085780638da5cb5b14610124578063f2fde38b146101425761007d565b806352f9753614610082578063715018a6146100b257806378755295146100bc575b600080fd5b61009c6004803603810190610097919061055d565b61015e565b6040516100a991906105a5565b60405180910390f35b6100ba61017e565b005b6100d660048036038101906100d1919061055d565b610192565b6040516100e391906105a5565b60405180910390f35b6101066004803603810190610101919061055d565b6101bc565b005b610122600480360381019061011d919061055d565b610274565b005b61012c61032c565b6040516101399190610601565b60405180910390f35b61015c60048036038101906101579190610648565b610355565b005b60026020528060005260406000206000915054906101000a900460ff1681565b6101866103d8565b6101906000610456565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b600260015403610201576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f8906106d2565b60405180910390fd5b60026001819055506102116103d8565b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a26001808190555050565b6002600154036102b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102b0906106d2565b60405180910390fd5b60026001819055506102c96103d8565b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a26001808190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61035d6103d8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c390610764565b60405180910390fd5b6103d581610456565b50565b6103e061051a565b73ffffffffffffffffffffffffffffffffffffffff166103fe61032c565b73ffffffffffffffffffffffffffffffffffffffff1614610454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161044b906107d0565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b6000819050919050565b61053a81610527565b811461054557600080fd5b50565b60008135905061055781610531565b92915050565b60006020828403121561057357610572610522565b5b600061058184828501610548565b91505092915050565b60008115159050919050565b61059f8161058a565b82525050565b60006020820190506105ba6000830184610596565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105eb826105c0565b9050919050565b6105fb816105e0565b82525050565b600060208201905061061660008301846105f2565b92915050565b610625816105e0565b811461063057600080fd5b50565b6000813590506106428161061c565b92915050565b60006020828403121561065e5761065d610522565b5b600061066c84828501610633565b91505092915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006106bc601f83610675565b91506106c782610686565b602082019050919050565b600060208201905081810360008301526106eb816106af565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061074e602683610675565b9150610759826106f2565b604082019050919050565b6000602082019050818103600083015261077d81610741565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006107ba602083610675565b91506107c582610784565b602082019050919050565b600060208201905081810360008301526107e9816107ad565b905091905056fea26469706673582212207d5862aed4247dbb234886137c9816e9e56cd89739ad6fd4af7a4e275f66bd2b64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063865815971161005b57806386581597146100ec5780638767d9aa146101085780638da5cb5b14610124578063f2fde38b146101425761007d565b806352f9753614610082578063715018a6146100b257806378755295146100bc575b600080fd5b61009c6004803603810190610097919061055d565b61015e565b6040516100a991906105a5565b60405180910390f35b6100ba61017e565b005b6100d660048036038101906100d1919061055d565b610192565b6040516100e391906105a5565b60405180910390f35b6101066004803603810190610101919061055d565b6101bc565b005b610122600480360381019061011d919061055d565b610274565b005b61012c61032c565b6040516101399190610601565b60405180910390f35b61015c60048036038101906101579190610648565b610355565b005b60026020528060005260406000206000915054906101000a900460ff1681565b6101866103d8565b6101906000610456565b565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b600260015403610201576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f8906106d2565b60405180910390fd5b60026001819055506102116103d8565b60016002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fe4be98886a3c8cd9027fdb44065f6b81514c5cf5a1dab85eb7733beb531580ef60405160405180910390a26001808190555050565b6002600154036102b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102b0906106d2565b60405180910390fd5b60026001819055506102c96103d8565b60006002600083815260200190815260200160002060006101000a81548160ff021916908315150217905550807fa676ee7eed1b9e9e90c0ce1964919b8a084b891bafa6b778b64571f338c0cd9560405160405180910390a26001808190555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61035d6103d8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c390610764565b60405180910390fd5b6103d581610456565b50565b6103e061051a565b73ffffffffffffffffffffffffffffffffffffffff166103fe61032c565b73ffffffffffffffffffffffffffffffffffffffff1614610454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161044b906107d0565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b6000819050919050565b61053a81610527565b811461054557600080fd5b50565b60008135905061055781610531565b92915050565b60006020828403121561057357610572610522565b5b600061058184828501610548565b91505092915050565b60008115159050919050565b61059f8161058a565b82525050565b60006020820190506105ba6000830184610596565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105eb826105c0565b9050919050565b6105fb816105e0565b82525050565b600060208201905061061660008301846105f2565b92915050565b610625816105e0565b811461063057600080fd5b50565b6000813590506106428161061c565b92915050565b60006020828403121561065e5761065d610522565b5b600061066c84828501610633565b91505092915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006106bc601f83610675565b91506106c782610686565b602082019050919050565b600060208201905081810360008301526106eb816106af565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061074e602683610675565b9150610759826106f2565b604082019050919050565b6000602082019050818103600083015261077d81610741565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006107ba602083610675565b91506107c582610784565b602082019050919050565b600060208201905081810360008301526107e9816107ad565b905091905056fea26469706673582212207d5862aed4247dbb234886137c9816e9e56cd89739ad6fd4af7a4e275f66bd2b64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"ItemNotAllowed","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":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"allowedItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"isAllowed","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"setNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/LITToken.json b/deployments/rolluptestnet_987/LITToken.json deleted file mode 100644 index 18b2050..0000000 --- a/deployments/rolluptestnet_987/LITToken.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0xEb9368F7B7511A576C7F89C95AaEFa9269007F87","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280600c81526020017f4c69742050726f746f636f6c00000000000000000000000000000000000000008152506040518060400160405280600381526020017f4c4954000000000000000000000000000000000000000000000000000000000081525081600490816200008f919062000607565b508060059081620000a1919062000607565b505050620000d67fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42336200019260201b60201c565b620001087ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9336200019260201b60201c565b6200015a7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc97fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42620001a860201b60201c565b6200018c7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4280620001a860201b60201c565b620006ee565b620001a482826200020b60201b60201c565b5050565b6000620001bb83620002fc60201b60201c565b905081600080858152602001908152602001600020600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b6200021d82826200031b60201b60201c565b620002f857600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200029d6200038560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000806000838152602001908152602001600020600101549050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200040f57607f821691505b602082108103620004255762000424620003c7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200048f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000450565b6200049b868362000450565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620004e8620004e2620004dc84620004b3565b620004bd565b620004b3565b9050919050565b6000819050919050565b6200050483620004c7565b6200051c6200051382620004ef565b8484546200045d565b825550505050565b600090565b6200053362000524565b62000540818484620004f9565b505050565b5b8181101562000568576200055c60008262000529565b60018101905062000546565b5050565b601f821115620005b75762000581816200042b565b6200058c8462000440565b810160208510156200059c578190505b620005b4620005ab8562000440565b83018262000545565b50505b505050565b600082821c905092915050565b6000620005dc60001984600802620005bc565b1980831691505092915050565b6000620005f78383620005c9565b9150826002028217905092915050565b62000612826200038d565b67ffffffffffffffff8111156200062e576200062d62000398565b5b6200063a8254620003f6565b620006478282856200056c565b600060209050601f8311600181146200067f57600084156200066a578287015190505b620006768582620005e9565b865550620006e6565b601f1984166200068f866200042b565b60005b82811015620006b95784890151825560018201915060208501945060208101905062000692565b86831015620006d95784890151620006d5601f891682620005c9565b8355505b6001600288020188555050505b505050505050565b61260880620006fe6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806342966c68116100c3578063a217fddf1161007c578063a217fddf146103c4578063a457c2d7146103e2578063a9059cbb14610412578063d539139314610442578063d547741f14610460578063dd62ed3e1461047c5761014d565b806342966c68146102f057806370a082311461030c57806375b238fc1461033c57806379cc67901461035a57806391d148541461037657806395d89b41146103a65761014d565b8063248a9ca311610115578063248a9ca31461021e5780632f2ff15d1461024e578063313ce5671461026a57806336568abe1461028857806339509351146102a457806340c10f19146102d45761014d565b806301ffc9a71461015257806306fdde0314610182578063095ea7b3146101a057806318160ddd146101d057806323b872dd146101ee575b600080fd5b61016c6004803603810190610167919061182e565b6104ac565b6040516101799190611876565b60405180910390f35b61018a610526565b6040516101979190611921565b60405180910390f35b6101ba60048036038101906101b591906119d7565b6105b8565b6040516101c79190611876565b60405180910390f35b6101d86105db565b6040516101e59190611a26565b60405180910390f35b61020860048036038101906102039190611a41565b6105e5565b6040516102159190611876565b60405180910390f35b61023860048036038101906102339190611aca565b610614565b6040516102459190611b06565b60405180910390f35b61026860048036038101906102639190611b21565b610633565b005b610272610654565b60405161027f9190611b7d565b60405180910390f35b6102a2600480360381019061029d9190611b21565b61065d565b005b6102be60048036038101906102b991906119d7565b6106e0565b6040516102cb9190611876565b60405180910390f35b6102ee60048036038101906102e991906119d7565b610717565b005b61030a60048036038101906103059190611b98565b61078e565b005b61032660048036038101906103219190611bc5565b6107a2565b6040516103339190611a26565b60405180910390f35b6103446107eb565b6040516103519190611b06565b60405180910390f35b610374600480360381019061036f91906119d7565b61080f565b005b610390600480360381019061038b9190611b21565b61082f565b60405161039d9190611876565b60405180910390f35b6103ae610899565b6040516103bb9190611921565b60405180910390f35b6103cc61092b565b6040516103d99190611b06565b60405180910390f35b6103fc60048036038101906103f791906119d7565b610932565b6040516104099190611876565b60405180910390f35b61042c600480360381019061042791906119d7565b6109a9565b6040516104399190611876565b60405180910390f35b61044a6109cc565b6040516104579190611b06565b60405180910390f35b61047a60048036038101906104759190611b21565b6109f0565b005b61049660048036038101906104919190611bf2565b610a11565b6040516104a39190611a26565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061051f575061051e82610a98565b5b9050919050565b60606004805461053590611c61565b80601f016020809104026020016040519081016040528092919081815260200182805461056190611c61565b80156105ae5780601f10610583576101008083540402835291602001916105ae565b820191906000526020600020905b81548152906001019060200180831161059157829003601f168201915b5050505050905090565b6000806105c3610b02565b90506105d0818585610b0a565b600191505092915050565b6000600354905090565b6000806105f0610b02565b90506105fd858285610cd3565b610608858585610d5f565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61063c82610614565b61064581610fe1565b61064f8383610ff5565b505050565b60006012905090565b610665610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990611d04565b60405180910390fd5b6106dc82826110d5565b5050565b6000806106eb610b02565b905061070c8185856106fd8589610a11565b6107079190611d53565b610b0a565b600191505092915050565b6107417ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc93361082f565b610780576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077790611dd3565b60405180910390fd5b61078a82826111b6565b5050565b61079f610799610b02565b82611316565b50565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b6108218261081b610b02565b83610cd3565b61082b8282611316565b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600580546108a890611c61565b80601f01602080910402602001604051908101604052809291908181526020018280546108d490611c61565b80156109215780601f106108f657610100808354040283529160200191610921565b820191906000526020600020905b81548152906001019060200180831161090457829003601f168201915b5050505050905090565b6000801b81565b60008061093d610b02565b9050600061094b8286610a11565b905083811015610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098790611e65565b60405180910390fd5b61099d8286868403610b0a565b60019250505092915050565b6000806109b4610b02565b90506109c1818585610d5f565b600191505092915050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6109f982610614565b610a0281610fe1565b610a0c83836110d5565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7090611ef7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610be8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdf90611f89565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610cc69190611a26565b60405180910390a3505050565b6000610cdf8484610a11565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d595781811015610d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4290611ff5565b60405180910390fd5b610d588484848403610b0a565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc590612087565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3490612119565b60405180910390fd5b610e488383836114ee565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610ecf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec6906121ab565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f649190611d53565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610fc89190611a26565b60405180910390a3610fdb8484846114f3565b50505050565b610ff281610fed610b02565b6114f8565b50565b610fff828261082f565b6110d157600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611076610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6110df828261082f565b156111b257600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611157610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121c90612217565b60405180910390fd5b611231600083836114ee565b80600360008282546112439190611d53565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112999190611d53565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516112fe9190611a26565b60405180910390a3611312600083836114f3565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137c906122a9565b60405180910390fd5b611391826000836114ee565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f9061233b565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160036000828254611470919061235b565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114d59190611a26565b60405180910390a36114e9836000846114f3565b505050565b505050565b505050565b611502828261082f565b611591576115278173ffffffffffffffffffffffffffffffffffffffff166014611595565b6115358360001c6020611595565b604051602001611546929190612463565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115889190611921565b60405180910390fd5b5050565b6060600060028360026115a8919061249d565b6115b29190611d53565b67ffffffffffffffff8111156115cb576115ca6124df565b5b6040519080825280601f01601f1916602001820160405280156115fd5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106116355761163461250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106116995761169861250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026116d9919061249d565b6116e39190611d53565b90505b6001811115611783577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106117255761172461250e565b5b1a60f81b82828151811061173c5761173b61250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061177c9061253d565b90506116e6565b50600084146117c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117be906125b2565b60405180910390fd5b8091505092915050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61180b816117d6565b811461181657600080fd5b50565b60008135905061182881611802565b92915050565b600060208284031215611844576118436117d1565b5b600061185284828501611819565b91505092915050565b60008115159050919050565b6118708161185b565b82525050565b600060208201905061188b6000830184611867565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156118cb5780820151818401526020810190506118b0565b60008484015250505050565b6000601f19601f8301169050919050565b60006118f382611891565b6118fd818561189c565b935061190d8185602086016118ad565b611916816118d7565b840191505092915050565b6000602082019050818103600083015261193b81846118e8565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061196e82611943565b9050919050565b61197e81611963565b811461198957600080fd5b50565b60008135905061199b81611975565b92915050565b6000819050919050565b6119b4816119a1565b81146119bf57600080fd5b50565b6000813590506119d1816119ab565b92915050565b600080604083850312156119ee576119ed6117d1565b5b60006119fc8582860161198c565b9250506020611a0d858286016119c2565b9150509250929050565b611a20816119a1565b82525050565b6000602082019050611a3b6000830184611a17565b92915050565b600080600060608486031215611a5a57611a596117d1565b5b6000611a688682870161198c565b9350506020611a798682870161198c565b9250506040611a8a868287016119c2565b9150509250925092565b6000819050919050565b611aa781611a94565b8114611ab257600080fd5b50565b600081359050611ac481611a9e565b92915050565b600060208284031215611ae057611adf6117d1565b5b6000611aee84828501611ab5565b91505092915050565b611b0081611a94565b82525050565b6000602082019050611b1b6000830184611af7565b92915050565b60008060408385031215611b3857611b376117d1565b5b6000611b4685828601611ab5565b9250506020611b578582860161198c565b9150509250929050565b600060ff82169050919050565b611b7781611b61565b82525050565b6000602082019050611b926000830184611b6e565b92915050565b600060208284031215611bae57611bad6117d1565b5b6000611bbc848285016119c2565b91505092915050565b600060208284031215611bdb57611bda6117d1565b5b6000611be98482850161198c565b91505092915050565b60008060408385031215611c0957611c086117d1565b5b6000611c178582860161198c565b9250506020611c288582860161198c565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c7957607f821691505b602082108103611c8c57611c8b611c32565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000611cee602f8361189c565b9150611cf982611c92565b604082019050919050565b60006020820190508181036000830152611d1d81611ce1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611d5e826119a1565b9150611d69836119a1565b9250828201905080821115611d8157611d80611d24565b5b92915050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000611dbd60158361189c565b9150611dc882611d87565b602082019050919050565b60006020820190508181036000830152611dec81611db0565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611e4f60258361189c565b9150611e5a82611df3565b604082019050919050565b60006020820190508181036000830152611e7e81611e42565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611ee160248361189c565b9150611eec82611e85565b604082019050919050565b60006020820190508181036000830152611f1081611ed4565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000611f7360228361189c565b9150611f7e82611f17565b604082019050919050565b60006020820190508181036000830152611fa281611f66565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611fdf601d8361189c565b9150611fea82611fa9565b602082019050919050565b6000602082019050818103600083015261200e81611fd2565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061207160258361189c565b915061207c82612015565b604082019050919050565b600060208201905081810360008301526120a081612064565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061210360238361189c565b915061210e826120a7565b604082019050919050565b60006020820190508181036000830152612132816120f6565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061219560268361189c565b91506121a082612139565b604082019050919050565b600060208201905081810360008301526121c481612188565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000612201601f8361189c565b915061220c826121cb565b602082019050919050565b60006020820190508181036000830152612230816121f4565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061229360218361189c565b915061229e82612237565b604082019050919050565b600060208201905081810360008301526122c281612286565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b600061232560228361189c565b9150612330826122c9565b604082019050919050565b6000602082019050818103600083015261235481612318565b9050919050565b6000612366826119a1565b9150612371836119a1565b925082820390508181111561238957612388611d24565b5b92915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006123d060178361238f565b91506123db8261239a565b601782019050919050565b60006123f182611891565b6123fb818561238f565b935061240b8185602086016118ad565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061244d60118361238f565b915061245882612417565b601182019050919050565b600061246e826123c3565b915061247a82856123e6565b915061248582612440565b915061249182846123e6565b91508190509392505050565b60006124a8826119a1565b91506124b3836119a1565b92508282026124c1816119a1565b915082820484148315176124d8576124d7611d24565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612548826119a1565b91506000820361255b5761255a611d24565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600061259c60208361189c565b91506125a782612566565b602082019050919050565b600060208201905081810360008301526125cb8161258f565b905091905056fea26469706673582212209586bf339fa1163cd157e331a4964ca3bfdd8750a30d146c568ca6d32ba5553e64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061014d5760003560e01c806342966c68116100c3578063a217fddf1161007c578063a217fddf146103c4578063a457c2d7146103e2578063a9059cbb14610412578063d539139314610442578063d547741f14610460578063dd62ed3e1461047c5761014d565b806342966c68146102f057806370a082311461030c57806375b238fc1461033c57806379cc67901461035a57806391d148541461037657806395d89b41146103a65761014d565b8063248a9ca311610115578063248a9ca31461021e5780632f2ff15d1461024e578063313ce5671461026a57806336568abe1461028857806339509351146102a457806340c10f19146102d45761014d565b806301ffc9a71461015257806306fdde0314610182578063095ea7b3146101a057806318160ddd146101d057806323b872dd146101ee575b600080fd5b61016c6004803603810190610167919061182e565b6104ac565b6040516101799190611876565b60405180910390f35b61018a610526565b6040516101979190611921565b60405180910390f35b6101ba60048036038101906101b591906119d7565b6105b8565b6040516101c79190611876565b60405180910390f35b6101d86105db565b6040516101e59190611a26565b60405180910390f35b61020860048036038101906102039190611a41565b6105e5565b6040516102159190611876565b60405180910390f35b61023860048036038101906102339190611aca565b610614565b6040516102459190611b06565b60405180910390f35b61026860048036038101906102639190611b21565b610633565b005b610272610654565b60405161027f9190611b7d565b60405180910390f35b6102a2600480360381019061029d9190611b21565b61065d565b005b6102be60048036038101906102b991906119d7565b6106e0565b6040516102cb9190611876565b60405180910390f35b6102ee60048036038101906102e991906119d7565b610717565b005b61030a60048036038101906103059190611b98565b61078e565b005b61032660048036038101906103219190611bc5565b6107a2565b6040516103339190611a26565b60405180910390f35b6103446107eb565b6040516103519190611b06565b60405180910390f35b610374600480360381019061036f91906119d7565b61080f565b005b610390600480360381019061038b9190611b21565b61082f565b60405161039d9190611876565b60405180910390f35b6103ae610899565b6040516103bb9190611921565b60405180910390f35b6103cc61092b565b6040516103d99190611b06565b60405180910390f35b6103fc60048036038101906103f791906119d7565b610932565b6040516104099190611876565b60405180910390f35b61042c600480360381019061042791906119d7565b6109a9565b6040516104399190611876565b60405180910390f35b61044a6109cc565b6040516104579190611b06565b60405180910390f35b61047a60048036038101906104759190611b21565b6109f0565b005b61049660048036038101906104919190611bf2565b610a11565b6040516104a39190611a26565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061051f575061051e82610a98565b5b9050919050565b60606004805461053590611c61565b80601f016020809104026020016040519081016040528092919081815260200182805461056190611c61565b80156105ae5780601f10610583576101008083540402835291602001916105ae565b820191906000526020600020905b81548152906001019060200180831161059157829003601f168201915b5050505050905090565b6000806105c3610b02565b90506105d0818585610b0a565b600191505092915050565b6000600354905090565b6000806105f0610b02565b90506105fd858285610cd3565b610608858585610d5f565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61063c82610614565b61064581610fe1565b61064f8383610ff5565b505050565b60006012905090565b610665610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990611d04565b60405180910390fd5b6106dc82826110d5565b5050565b6000806106eb610b02565b905061070c8185856106fd8589610a11565b6107079190611d53565b610b0a565b600191505092915050565b6107417ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc93361082f565b610780576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077790611dd3565b60405180910390fd5b61078a82826111b6565b5050565b61079f610799610b02565b82611316565b50565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b6108218261081b610b02565b83610cd3565b61082b8282611316565b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600580546108a890611c61565b80601f01602080910402602001604051908101604052809291908181526020018280546108d490611c61565b80156109215780601f106108f657610100808354040283529160200191610921565b820191906000526020600020905b81548152906001019060200180831161090457829003601f168201915b5050505050905090565b6000801b81565b60008061093d610b02565b9050600061094b8286610a11565b905083811015610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098790611e65565b60405180910390fd5b61099d8286868403610b0a565b60019250505092915050565b6000806109b4610b02565b90506109c1818585610d5f565b600191505092915050565b7ff0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc981565b6109f982610614565b610a0281610fe1565b610a0c83836110d5565b505050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7090611ef7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610be8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdf90611f89565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610cc69190611a26565b60405180910390a3505050565b6000610cdf8484610a11565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d595781811015610d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4290611ff5565b60405180910390fd5b610d588484848403610b0a565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc590612087565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3490612119565b60405180910390fd5b610e488383836114ee565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610ecf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec6906121ab565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f649190611d53565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610fc89190611a26565b60405180910390a3610fdb8484846114f3565b50505050565b610ff281610fed610b02565b6114f8565b50565b610fff828261082f565b6110d157600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611076610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6110df828261082f565b156111b257600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611157610b02565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121c90612217565b60405180910390fd5b611231600083836114ee565b80600360008282546112439190611d53565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112999190611d53565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516112fe9190611a26565b60405180910390a3611312600083836114f3565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137c906122a9565b60405180910390fd5b611391826000836114ee565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f9061233b565b60405180910390fd5b818103600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160036000828254611470919061235b565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114d59190611a26565b60405180910390a36114e9836000846114f3565b505050565b505050565b505050565b611502828261082f565b611591576115278173ffffffffffffffffffffffffffffffffffffffff166014611595565b6115358360001c6020611595565b604051602001611546929190612463565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115889190611921565b60405180910390fd5b5050565b6060600060028360026115a8919061249d565b6115b29190611d53565b67ffffffffffffffff8111156115cb576115ca6124df565b5b6040519080825280601f01601f1916602001820160405280156115fd5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106116355761163461250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106116995761169861250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026116d9919061249d565b6116e39190611d53565b90505b6001811115611783577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106117255761172461250e565b5b1a60f81b82828151811061173c5761173b61250e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061177c9061253d565b90506116e6565b50600084146117c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117be906125b2565b60405180910390fd5b8091505092915050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61180b816117d6565b811461181657600080fd5b50565b60008135905061182881611802565b92915050565b600060208284031215611844576118436117d1565b5b600061185284828501611819565b91505092915050565b60008115159050919050565b6118708161185b565b82525050565b600060208201905061188b6000830184611867565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156118cb5780820151818401526020810190506118b0565b60008484015250505050565b6000601f19601f8301169050919050565b60006118f382611891565b6118fd818561189c565b935061190d8185602086016118ad565b611916816118d7565b840191505092915050565b6000602082019050818103600083015261193b81846118e8565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061196e82611943565b9050919050565b61197e81611963565b811461198957600080fd5b50565b60008135905061199b81611975565b92915050565b6000819050919050565b6119b4816119a1565b81146119bf57600080fd5b50565b6000813590506119d1816119ab565b92915050565b600080604083850312156119ee576119ed6117d1565b5b60006119fc8582860161198c565b9250506020611a0d858286016119c2565b9150509250929050565b611a20816119a1565b82525050565b6000602082019050611a3b6000830184611a17565b92915050565b600080600060608486031215611a5a57611a596117d1565b5b6000611a688682870161198c565b9350506020611a798682870161198c565b9250506040611a8a868287016119c2565b9150509250925092565b6000819050919050565b611aa781611a94565b8114611ab257600080fd5b50565b600081359050611ac481611a9e565b92915050565b600060208284031215611ae057611adf6117d1565b5b6000611aee84828501611ab5565b91505092915050565b611b0081611a94565b82525050565b6000602082019050611b1b6000830184611af7565b92915050565b60008060408385031215611b3857611b376117d1565b5b6000611b4685828601611ab5565b9250506020611b578582860161198c565b9150509250929050565b600060ff82169050919050565b611b7781611b61565b82525050565b6000602082019050611b926000830184611b6e565b92915050565b600060208284031215611bae57611bad6117d1565b5b6000611bbc848285016119c2565b91505092915050565b600060208284031215611bdb57611bda6117d1565b5b6000611be98482850161198c565b91505092915050565b60008060408385031215611c0957611c086117d1565b5b6000611c178582860161198c565b9250506020611c288582860161198c565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c7957607f821691505b602082108103611c8c57611c8b611c32565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000611cee602f8361189c565b9150611cf982611c92565b604082019050919050565b60006020820190508181036000830152611d1d81611ce1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611d5e826119a1565b9150611d69836119a1565b9250828201905080821115611d8157611d80611d24565b5b92915050565b7f4c4954546f6b656e3a206f6e6c79206d696e7465720000000000000000000000600082015250565b6000611dbd60158361189c565b9150611dc882611d87565b602082019050919050565b60006020820190508181036000830152611dec81611db0565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611e4f60258361189c565b9150611e5a82611df3565b604082019050919050565b60006020820190508181036000830152611e7e81611e42565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611ee160248361189c565b9150611eec82611e85565b604082019050919050565b60006020820190508181036000830152611f1081611ed4565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000611f7360228361189c565b9150611f7e82611f17565b604082019050919050565b60006020820190508181036000830152611fa281611f66565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611fdf601d8361189c565b9150611fea82611fa9565b602082019050919050565b6000602082019050818103600083015261200e81611fd2565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061207160258361189c565b915061207c82612015565b604082019050919050565b600060208201905081810360008301526120a081612064565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061210360238361189c565b915061210e826120a7565b604082019050919050565b60006020820190508181036000830152612132816120f6565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061219560268361189c565b91506121a082612139565b604082019050919050565b600060208201905081810360008301526121c481612188565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000612201601f8361189c565b915061220c826121cb565b602082019050919050565b60006020820190508181036000830152612230816121f4565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061229360218361189c565b915061229e82612237565b604082019050919050565b600060208201905081810360008301526122c281612286565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b600061232560228361189c565b9150612330826122c9565b604082019050919050565b6000602082019050818103600083015261235481612318565b9050919050565b6000612366826119a1565b9150612371836119a1565b925082820390508181111561238957612388611d24565b5b92915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006123d060178361238f565b91506123db8261239a565b601782019050919050565b60006123f182611891565b6123fb818561238f565b935061240b8185602086016118ad565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061244d60118361238f565b915061245882612417565b601182019050919050565b600061246e826123c3565b915061247a82856123e6565b915061248582612440565b915061249182846123e6565b91508190509392505050565b60006124a8826119a1565b91506124b3836119a1565b92508282026124c1816119a1565b915082820484148315176124d8576124d7611d24565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612548826119a1565b91506000820361255b5761255a611d24565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600061259c60208361189c565b91506125a782612566565b602082019050919050565b600060208201905081810360008301526125cb8161258f565b905091905056fea26469706673582212209586bf339fa1163cd157e331a4964ca3bfdd8750a30d146c568ca6d32ba5553e64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ADMIN_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":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/Multisender.json b/deployments/rolluptestnet_987/Multisender.json deleted file mode 100644 index 1a11a6d..0000000 --- a/deployments/rolluptestnet_987/Multisender.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Multisender.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\n// This contract does one thing, simply. it allows you to send eth or tokens to multiple recipients. Useful for setting up a testnet and funding all the validators and stakers.\\n\\ncontract Multisender is Ownable {\\n function sendEth(address[] calldata _recipients) public payable {\\n uint256 val = msg.value / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n payable(_recipients[i]).transfer(val);\\n }\\n }\\n\\n function sendTokens(address[] calldata _recipients, address tokenContract)\\n public\\n {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n uint256 val = bal / _recipients.length;\\n for (uint256 i = 0; i < _recipients.length; i++) {\\n tkn.transfer(_recipients[i], val);\\n }\\n }\\n\\n function withdraw() public onlyOwner {\\n payable(msg.sender).transfer(address(this).balance);\\n }\\n\\n function withdrawTokens(address tokenContract) public onlyOwner {\\n ERC20 tkn = ERC20(tokenContract);\\n uint256 bal = tkn.balanceOf(address(this));\\n tkn.transfer(msg.sender, bal);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x6bB926413917F32C0A3153BF94e4bb3bC98cB127","bytecode":"0x608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b610bf98061010d6000396000f3fe6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","deployedBytecode":"0x6080604052600436106100705760003560e01c80636ecf13861161004e5780636ecf1386146100d1578063715018a6146100fa5780638da5cb5b14610111578063f2fde38b1461013c57610070565b80633b2fe781146100755780633ccfd60b1461009157806349df728c146100a8575b600080fd5b61008f600480360381019061008a919061074c565b610165565b005b34801561009d57600080fd5b506100a661020d565b005b3480156100b457600080fd5b506100cf60048036038101906100ca91906107f7565b61025e565b005b3480156100dd57600080fd5b506100f860048036038101906100f39190610824565b61036d565b005b34801561010657600080fd5b5061010f6104d3565b005b34801561011d57600080fd5b506101266104e7565b6040516101339190610893565b60405180910390f35b34801561014857600080fd5b50610163600480360381019061015e91906107f7565b610510565b005b600082829050346101769190610916565b905060005b838390508110156102075783838281811061019957610198610947565b5b90506020020160208101906101ae91906107f7565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156101f3573d6000803e3d6000fd5b5080806101ff90610976565b91505061017b565b50505050565b610215610593565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561025b573d6000803e3d6000fd5b50565b610266610593565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016102a69190610893565b602060405180830381865afa1580156102c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e791906109ea565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610324929190610a26565b6020604051808303816000875af1158015610343573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103679190610a87565b50505050565b600081905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103ad9190610893565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee91906109ea565b9050600085859050826104019190610916565b905060005b868690508110156104ca578373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8888848181106104405761043f610947565b5b905060200201602081019061045591906107f7565b846040518363ffffffff1660e01b8152600401610473929190610a26565b6020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610a87565b5080806104c290610976565b915050610406565b50505050505050565b6104db610593565b6104e56000610611565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610518610593565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90610b37565b60405180910390fd5b61059081610611565b50565b61059b6106d5565b73ffffffffffffffffffffffffffffffffffffffff166105b96104e7565b73ffffffffffffffffffffffffffffffffffffffff161461060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060690610ba3565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261070c5761070b6106e7565b5b8235905067ffffffffffffffff811115610729576107286106ec565b5b602083019150836020820283011115610745576107446106f1565b5b9250929050565b60008060208385031215610763576107626106dd565b5b600083013567ffffffffffffffff811115610781576107806106e2565b5b61078d858286016106f6565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107c482610799565b9050919050565b6107d4816107b9565b81146107df57600080fd5b50565b6000813590506107f1816107cb565b92915050565b60006020828403121561080d5761080c6106dd565b5b600061081b848285016107e2565b91505092915050565b60008060006040848603121561083d5761083c6106dd565b5b600084013567ffffffffffffffff81111561085b5761085a6106e2565b5b610867868287016106f6565b9350935050602061087a868287016107e2565b9150509250925092565b61088d816107b9565b82525050565b60006020820190506108a86000830184610884565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610921826108ae565b915061092c836108ae565b92508261093c5761093b6108b8565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610981826108ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109b3576109b26108e7565b5b600182019050919050565b6109c7816108ae565b81146109d257600080fd5b50565b6000815190506109e4816109be565b92915050565b600060208284031215610a00576109ff6106dd565b5b6000610a0e848285016109d5565b91505092915050565b610a20816108ae565b82525050565b6000604082019050610a3b6000830185610884565b610a486020830184610a17565b9392505050565b60008115159050919050565b610a6481610a4f565b8114610a6f57600080fd5b50565b600081519050610a8181610a5b565b92915050565b600060208284031215610a9d57610a9c6106dd565b5b6000610aab84828501610a72565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610b21602683610ab4565b9150610b2c82610ac5565b604082019050919050565b60006020820190508181036000830152610b5081610b14565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610b8d602083610ab4565b9150610b9882610b57565b602082019050919050565b60006020820190508181036000830152610bbc81610b80565b905091905056fea26469706673582212208974f7d1cc9bcfeb3dc86bd44f1d551e4548f66e9a0f6b0cc1bd235f4423141d64736f6c63430008110033","abi":[{"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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"}],"name":"sendEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"address","name":"tokenContract","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/PKPNFTMetadata.json b/deployments/rolluptestnet_987/PKPNFTMetadata.json deleted file mode 100644 index 06b8950..0000000 --- a/deployments/rolluptestnet_987/PKPNFTMetadata.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x5911a5E665B6acfED69201512032d6168A231f61","bytecode":"0x608060405234801561001057600080fd5b506117de806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063451d89fa1461003b578063950462ee1461006b575b600080fd5b610055600480360381019061005091906109f1565b61009b565b6040516100629190610ab9565b60405180910390f35b61008560048036038101906100809190610b6f565b6102c0565b6040516100929190610ab9565b60405180910390f35b60606000600283516100ad9190610c0d565b67ffffffffffffffff8111156100c6576100c56108c6565b5b6040519080825280601f01601f1916602001820160405280156100f85781602001600182028036833780820191505090505b50905060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060005b84518110156102965781825186838151811061015757610156610c4f565b5b602001015160f81c60f81b60f81c60ff166101729190610cad565b8151811061018357610182610c4f565b5b602001015160f81c60f81b8360028361019c9190610c0d565b815181106101ad576101ac610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508182518683815181106101f2576101f1610c4f565b5b602001015160f81c60f81b60f81c60ff1661020d9190610cde565b8151811061021e5761021d610c4f565b5b602001015160f81c60f81b8360016002846102399190610c0d565b6102439190610d0f565b8151811061025457610253610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061028e90610d43565b915050610138565b50816040516020016102a89190610e29565b60405160208183030381529060405292505050919050565b6060600060405180610480016040528061045681526020016113136104569139905060006102ed8561009b565b905060006102fa8561036b565b9050600061030788610398565b9050600061033b828686868660405160200161032795949392919061114e565b6040516020818303038152906040526104f8565b90508060405160200161034e9190611227565b604051602081830303815290604052955050505050509392505050565b60606103918273ffffffffffffffffffffffffffffffffffffffff16601460ff1661065b565b9050919050565b6060600082036103df576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506104f3565b600082905060005b600082146104115780806103fa90610d43565b915050600a8261040a9190610cad565b91506103e7565b60008167ffffffffffffffff81111561042d5761042c6108c6565b5b6040519080825280601f01601f19166020018201604052801561045f5781602001600182028036833780820191505090505b5090505b600085146104ec576001826104789190611249565b9150600a856104879190610cde565b60306104939190610d0f565b60f81b8183815181106104a9576104a8610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856104e59190610cad565b9450610463565b8093505050505b919050565b6060600082510361051a57604051806020016040528060008152509050610656565b600060405180606001604052806040815260200161176960409139905060006003600285516105499190610d0f565b6105539190610cad565b600461055f9190610c0d565b67ffffffffffffffff811115610578576105776108c6565b5b6040519080825280601f01601f1916602001820160405280156105aa5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015610616576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506105bb565b505060038651066001811461063257600281146106455761064d565b603d6001830353603d600283035361064d565b603d60018303535b50505080925050505b919050565b60606000600283600261066e9190610c0d565b6106789190610d0f565b67ffffffffffffffff811115610691576106906108c6565b5b6040519080825280601f01601f1916602001820160405280156106c35781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106106fb576106fa610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061075f5761075e610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261079f9190610c0d565b6107a99190610d0f565b90505b6001811115610849577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106107eb576107ea610c4f565b5b1a60f81b82828151811061080257610801610c4f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806108429061127d565b90506107ac565b506000841461088d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610884906112f2565b60405180910390fd5b8091505092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6108fe826108b5565b810181811067ffffffffffffffff8211171561091d5761091c6108c6565b5b80604052505050565b6000610930610897565b905061093c82826108f5565b919050565b600067ffffffffffffffff82111561095c5761095b6108c6565b5b610965826108b5565b9050602081019050919050565b82818337600083830152505050565b600061099461098f84610941565b610926565b9050828152602081018484840111156109b0576109af6108b0565b5b6109bb848285610972565b509392505050565b600082601f8301126109d8576109d76108ab565b5b81356109e8848260208601610981565b91505092915050565b600060208284031215610a0757610a066108a1565b5b600082013567ffffffffffffffff811115610a2557610a246108a6565b5b610a31848285016109c3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a74578082015181840152602081019050610a59565b60008484015250505050565b6000610a8b82610a3a565b610a958185610a45565b9350610aa5818560208601610a56565b610aae816108b5565b840191505092915050565b60006020820190508181036000830152610ad38184610a80565b905092915050565b6000819050919050565b610aee81610adb565b8114610af957600080fd5b50565b600081359050610b0b81610ae5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b3c82610b11565b9050919050565b610b4c81610b31565b8114610b5757600080fd5b50565b600081359050610b6981610b43565b92915050565b600080600060608486031215610b8857610b876108a1565b5b6000610b9686828701610afc565b935050602084013567ffffffffffffffff811115610bb757610bb66108a6565b5b610bc3868287016109c3565b9250506040610bd486828701610b5a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610c1882610adb565b9150610c2383610adb565b9250828202610c3181610adb565b91508282048414831517610c4857610c47610bde565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610cb882610adb565b9150610cc383610adb565b925082610cd357610cd2610c7e565b5b828204905092915050565b6000610ce982610adb565b9150610cf483610adb565b925082610d0457610d03610c7e565b5b828206905092915050565b6000610d1a82610adb565b9150610d2583610adb565b9250828201905080821115610d3d57610d3c610bde565b5b92915050565b6000610d4e82610adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8057610d7f610bde565b5b600182019050919050565b600081905092915050565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b6000610dcc600283610d8b565b9150610dd782610d96565b600282019050919050565b600081519050919050565b600081905092915050565b6000610e0382610de2565b610e0d8185610ded565b9350610e1d818560208601610a56565b80840191505092915050565b6000610e3482610dbf565b9150610e408284610df8565b915081905092915050565b7f7b226e616d65223a20224c697420504b50202300000000000000000000000000600082015250565b6000610e81601383610d8b565b9150610e8c82610e4b565b601382019050919050565b6000610ea282610a3a565b610eac8185610d8b565b9350610ebc818560208601610a56565b80840191505092915050565b7f222c20226465736372697074696f6e223a202254686973204e465420656e746960008201527f746c65732074686520686f6c64657220746f207573652061204c69742050726f60208201527f746f636f6c20504b502c20616e6420746f206772616e7420616363657373207460408201527f6f206f7468657220757365727320616e64204c697420416374696f6e7320746f60608201527f20757365207468697320504b50222c2022696d6167655f64617461223a202200608082015250565b6000610f96609f83610d8b565b9150610fa182610ec8565b609f82019050919050565b7f222c2261747472696275746573223a205b7b2274726169745f74797065223a2060008201527f225075626c6963204b6579222c202276616c7565223a20220000000000000000602082015250565b6000611008603883610d8b565b915061101382610fac565b603882019050919050565b7f227d2c207b2274726169745f74797065223a20224554482057616c6c6574204160008201527f646472657373222c202276616c7565223a202200000000000000000000000000602082015250565b600061107a603383610d8b565b91506110858261101e565b603382019050919050565b7f227d2c207b2274726169745f74797065223a2022546f6b656e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b60006110ec602983610d8b565b91506110f782611090565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000600082015250565b6000611138600483610d8b565b915061114382611102565b600482019050919050565b600061115982610e74565b91506111658288610e97565b915061117082610f89565b915061117c8287610df8565b915061118782610ffb565b91506111938286610e97565b915061119e8261106d565b91506111aa8285610e97565b91506111b5826110df565b91506111c18284610e97565b91506111cc8261112b565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000611211601d83610d8b565b915061121c826111db565b601d82019050919050565b600061123282611204565b915061123e8284610e97565b915081905092915050565b600061125482610adb565b915061125f83610adb565b925082820390508181111561127757611276610bde565b5b92915050565b600061128882610adb565b91506000820361129b5761129a610bde565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006112dc602083610a45565b91506112e7826112a6565b602082019050919050565b6000602082019050818103600083015261130b816112cf565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf1147ada11a22dc87ce14df5a91becc05940bc778d2125e6341339a8bac633c64736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"buffer","type":"bytes"}],"name":"bytesToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"address","name":"ethAddress","type":"address"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/PKPPermissions.json b/deployments/rolluptestnet_987/PKPPermissions.json deleted file mode 100644 index de11b87..0000000 --- a/deployments/rolluptestnet_987/PKPPermissions.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x809E136C67A7f0b6b4F8FF71d8D5bCb1F21d2427","bytecode":"0x60806040523480156200001157600080fd5b5060405162005087380380620050878339818101604052810190620000379190620001d5565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000207565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b620001af8162000190565b8114620001bb57600080fd5b50565b600081519050620001cf81620001a4565b92915050565b600060208284031215620001ee57620001ed6200016b565b5b6000620001fe84828501620001be565b91505092915050565b614e7080620002176000396000f3fe608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea264697066735822122097f120614501882fa47939caed2da0c057e01242fb93eb22f1f7662fb5cf27e464736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b50600436106101d75760003560e01c80638a43157811610104578063bb7a1070116100a2578063f2fde38b11610071578063f2fde38b146105be578063f34f21ba146105da578063fceb39831461060a578063ffa2e9531461063a576101d7565b8063bb7a107014610512578063bd4986a014610542578063d41a327214610572578063ef6fd8781461058e576101d7565b8063a1afdc6f116100de578063a1afdc6f14610466578063a1c805fa14610496578063abc541ae146104c6578063b997606f146104f6576101d7565b80638a431578146104105780638da5cb5b1461042c5780639dd4349b1461044a576101d7565b80635521c4521161017c5780636821c8e21161014b5780636821c8e21461039e578063715018a6146103ba57806378c49efa146103c457806382559561146103f4576101d7565b80635521c45214610306578063557b5eba1461033657806366fc6541146103665780636705c6f214610382576101d7565b80631663c121116101b85780631663c1211461026c578063176354fd146102885780632657768b146102a457806345b72bde146102d6576101d7565b80618b4f146101dc578062221c081461020c5780630a60950d1461023c575b600080fd5b6101f660048036038101906101f19190613309565b610658565b6040516102039190613364565b60405180910390f35b610226600480360381019061022191906133e4565b610770565b604051610233919061352a565b60405180910390f35b6102566004803603810190610251919061368d565b61089f565b60405161026391906136f8565b60405180910390f35b61028660048036038101906102819190613769565b6108d5565b005b6102a2600480360381019061029d91906137dd565b610942565b005b6102be60048036038101906102b9919061380a565b61098e565b6040516102cd939291906138b6565b60405180910390f35b6102f060048036038101906102eb91906139f4565b610ac8565b6040516102fd9190613364565b60405180910390f35b610320600480360381019061031b9190613a77565b610b1d565b60405161032d9190613b95565b60405180910390f35b610350600480360381019061034b9190613bb7565b610c4d565b60405161035d9190613364565b60405180910390f35b610380600480360381019061037b9190613bb7565b610ca3565b005b61039c60048036038101906103979190613c26565b610e5a565b005b6103b860048036038101906103b391906133e4565b610fd2565b005b6103c26111b1565b005b6103de60048036038101906103d99190613d68565b6111c5565b6040516103eb9190613364565b60405180910390f35b61040e600480360381019061040991906133e4565b61121c565b005b61042a60048036038101906104259190613e37565b6113fb565b005b61043461148e565b6040516104419190613edb565b60405180910390f35b610464600480360381019061045f9190613f9c565b6114b7565b005b610480600480360381019061047b9190613a77565b61182d565b60405161048d919061402c565b60405180910390f35b6104b060048036038101906104ab91906133e4565b6119e1565b6040516104bd9190613364565b60405180910390f35b6104e060048036038101906104db919061380a565b611a7c565b6040516104ed919061410c565b60405180910390f35b610510600480360381019061050b9190613309565b6120f9565b005b61052c6004803603810190610527919061380a565b61213a565b604051610539919061423a565b60405180910390f35b61055c6004803603810190610557919061380a565b61256c565b6040516105699190613edb565b60405180910390f35b61058c60048036038101906105879190613a77565b612611565b005b6105a860048036038101906105a3919061380a565b612678565b6040516105b5919061402c565b60405180910390f35b6105d860048036038101906105d391906137dd565b612722565b005b6105f460048036038101906105ef919061380a565b6127a5565b6040516106019190614375565b60405180910390f35b610624600480360381019061061f9190613a77565b6129db565b6040516106319190613364565b60405180910390f35b610642612a48565b60405161064f91906143f6565b60405180910390f35b6000610697836001600681111561067257610671614411565b5b846040516020016106839190614488565b604051602081830303815290604052610c4d565b8061076857508173ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161070f91906136f8565b602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906144b8565b73ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b606060006107c28686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000600360008981526020019081526020016000206000838152602001908152602001600020905060008467ffffffffffffffff81111561080857610807613562565b5b6040519080825280602002602001820160405280156108365781602001602082028036833780820191505090505b50905060005b8581101561088f576108578184612a6e90919063ffffffff16565b82828151811061086a576108696144e5565b5b602002602001019015159081151581525050808061088790614543565b91505061083c565b5080935050505095945050505050565b600082826040516020016108b492919061458b565b6040516020818303038152906040528051906020012060001c905092915050565b61093c846040518060600160405280600160068111156108f8576108f7614411565b5b81526020018660405160200161090e9190614488565b60405160208183030381529060405281526020016040518060200160405280600081525081525084846114b7565b50505050565b61094a612aaa565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508060000154908060010180546109b7906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546109e3906145ea565b8015610a305780601f10610a0557610100808354040283529160200191610a30565b820191906000526020600020905b815481529060010190602001808311610a1357829003601f168201915b505050505090806002018054610a45906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054610a71906145ea565b8015610abe5780601f10610a9357610100808354040283529160200191610abe565b820191906000526020600020905b815481529060010190602001808311610aa157829003601f168201915b5050505050905083565b6000806006600087815260200190815260200160002060008681526020019081526020016000205490506000801b8103610b06576000915050610b15565b610b11848285612b28565b9150505b949350505050565b60606000610b6f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000610b8e60056000848152602001908152602001600020612b3f565b905060008167ffffffffffffffff811115610bac57610bab613562565b5b604051908082528060200260200182016040528015610bda5781602001602082028036833780820191505090505b50905060005b82811015610c3f57610c0d8160056000878152602001908152602001600020612b5490919063ffffffff16565b828281518110610c2057610c1f6144e5565b5b6020026020010181815250508080610c3790614543565b915050610be0565b508093505050509392505050565b600080610c5a848461089f565b90506000610c838260026000898152602001908152602001600020612b6e90919063ffffffff16565b905080610c9557600092505050610c9c565b6001925050505b9392505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d0191906136f8565b602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610db2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da990614678565b60405180910390fd5b6000610dbe858561089f565b90506000600260008881526020019081526020016000209050610dea8282612b8890919063ffffffff16565b506000600560008481526020019081526020016000209050610e158882612b8890919063ffffffff16565b50877f9830658acd6a41f1cb12b425ed83cb2b8ccbfa753337cd13be80be51fc3f33738488604051610e4892919061458b565b60405180910390a25050505050505050565b826000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610eb891906136f8565b602060405180830381865afa158015610ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef991906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6090614678565b60405180910390fd5b826006600087815260200190815260200160002060008681526020019081526020016000208190555083857fd4beb656267200ccd79d73dbdfbad162c213e10ebad16508f22cb4df8d3259ad85604051610fc391906146a7565b60405180910390a35050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161103091906136f8565b602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d890614678565b60405180910390fd5b60006111318787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b905061116984600360008b81526020019081526020016000206000848152602001908152602001600020612ba290919063ffffffff16565b877f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e8288888860405161119f94939291906146ef565b60405180910390a25050505050505050565b6111b9612aaa565b6111c36000612be0565b565b6000806006600088815260200190815260200160002060008781526020019081526020016000205490506000801b8103611203576000915050611213565b61120f85858386612ca4565b9150505b95945050505050565b846000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161127a91906136f8565b602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb91906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132290614678565b60405180910390fd5b600061137b8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506113b384600360008b81526020019081526020016000206000848152602001908152602001600020612cbd90919063ffffffff16565b877f49bb3a0761ed218e1db1e9c41096ed35188868994cc37a32e1f25855745b424e888888886040516113e994939291906146ef565b60405180910390a25050505050505050565b6114878560405180606001604052806002600681111561141e5761141d614411565b5b815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016040518060200160405280600081525081525084846114b7565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b836000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151591906136f8565b602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906144b8565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90614678565b60405180910390fd5b60006115da8660000151876020015161089f565b905060006004600083815260200190815260200160002060020180546115ff906145ea565b9050148061164157508560400151805190602001206004600083815260200190815260200160002060020160405161163791906147d2565b6040518091039020145b611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790614881565b60405180910390fd5b85600460008381526020019081526020016000206000820151816000015560208201518160010190816116b39190614a2e565b5060408201518160020190816116c99190614a2e565b5090505060006002600089815260200190815260200160002090506116f78282612cfc90919063ffffffff16565b5060006005600084815260200190815260200160002090506117228982612cfc90919063ffffffff16565b5060005b878790508110156117d9576000888883818110611746576117456144e5565b5b90506020020135905061178581600360008e81526020019081526020016000206000888152602001908152602001600020612ba290919063ffffffff16565b8a7f29eb060f266aff306ec81b612728a417406dd6298f8f7576a37b4e6830dcc60e868c60200151846040516117bd93929190614b00565b60405180910390a25080806117d190614543565b915050611726565b50887fd7db314a62650aaa1b15d4bb5c95c558a03cde3ee7f36e144b73126a3a8e839a89600001518a602001518b6040015160405161181a939291906138b6565b60405180910390a2505050505050505050565b6060600061187f8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546118bb906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546118e7906145ea565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050815260200160028201805461194d906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611979906145ea565b80156119c65780601f1061199b576101008083540402835291602001916119c6565b820191906000526020600020905b8154815290600101906020018083116119a957829003601f168201915b50505050508152505090508060400151925050509392505050565b600080611a328686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061089f565b90506000611a6c84600360008b81526020019081526020016000206000858152602001908152602001600020612a6e90919063ffffffff16565b9050809250505095945050505050565b60606000611a9b60026000858152602001908152602001600020612b3f565b90506000805b82811015611c64576000611ad08260026000898152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611b0c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906145ea565b8015611b855780601f10611b5a57610100808354040283529160200191611b85565b820191906000526020600020905b815481529060010190602001808311611b6857829003601f168201915b50505050508152602001600282018054611b9e906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611bca906145ea565b8015611c175780601f10611bec57610100808354040283529160200191611c17565b820191906000526020600020905b815481529060010190602001808311611bfa57829003601f168201915b505050505081525050905060016006811115611c3657611c35614411565b5b816000015103611c4f578380611c4b90614543565b9450505b50508080611c5c90614543565b915050611aa1565b506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f558e79866040518263ffffffff1660e01b8152600401611cc291906136f8565b602060405180830381865afa158015611cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d039190614b53565b9050606060008215611e6957600184611d1c9190614b80565b67ffffffffffffffff811115611d3557611d34613562565b5b604051908082528060200260200182016040528015611d635781602001602082028036833780820191505090505b5091506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e896040518263ffffffff1660e01b8152600401611dc391906136f8565b602060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0491906144b8565b90508083600081518110611e1b57611e1a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180611e6090614543565b92505050611eb5565b8367ffffffffffffffff811115611e8357611e82613562565b5b604051908082528060200260200182016040528015611eb15781602001602082028036833780820191505090505b5091505b60005b858110156120eb576000611ee782600260008c8152602001908152602001600020612b5490919063ffffffff16565b905060006004600083815260200190815260200160002060405180606001604052908160008201548152602001600182018054611f23906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4f906145ea565b8015611f9c5780601f10611f7157610100808354040283529160200191611f9c565b820191906000526020600020905b815481529060010190602001808311611f7f57829003601f168201915b50505050508152602001600282018054611fb5906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe1906145ea565b801561202e5780601f106120035761010080835404028352916020019161202e565b820191906000526020600020905b81548152906001019060200180831161201157829003601f168201915b50505050508152505090506001600681111561204d5761204c614411565b5b8160000151036120d657600080826020015190506c0100000000000000000000000060208201510491508187878151811061208b5761208a6144e5565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505085806120d090614543565b96505050505b505080806120e390614543565b915050611eb8565b508195505050505050919050565b612136826001600681111561211157612110614411565b5b836040516020016121229190614488565b604051602081830303815290604052610ca3565b5050565b6060600061215960026000858152602001908152602001600020612b3f565b90506000805b8281101561232257600061218e8260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546121ca906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546121f6906145ea565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050815260200160028201805461225c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612288906145ea565b80156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b5050505050815250509050600260068111156122f4576122f3614411565b5b81600001510361230d57838061230990614543565b9450505b5050808061231a90614543565b91505061215f565b5060008167ffffffffffffffff81111561233f5761233e613562565b5b60405190808252806020026020018201604052801561237257816020015b606081526020019060019003908161235d5790505b5090506000805b8481101561255f5760006123a882600260008b8152602001908152602001600020612b5490919063ffffffff16565b9050600060046000838152602001908152602001600020604051806060016040529081600082015481526020016001820180546123e4906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612410906145ea565b801561245d5780601f106124325761010080835404028352916020019161245d565b820191906000526020600020905b81548152906001019060200180831161244057829003601f168201915b50505050508152602001600282018054612476906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546124a2906145ea565b80156124ef5780601f106124c4576101008083540402835291602001916124ef565b820191906000526020600020905b8154815290600101906020018083116124d257829003601f168201915b50505050508152505090506002600681111561250e5761250d614411565b5b81600001510361254a5780602001518585815181106125305761252f6144e5565b5b6020026020010181905250838061254690614543565b9450505b5050808061255790614543565b915050612379565b5081945050505050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016125c991906136f8565b602060405180830381865afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906144b8565b9050919050565b612673836002600681111561262957612628614411565b5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610ca3565b505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ef6fd878836040518263ffffffff1660e01b81526004016126d591906136f8565b600060405180830381865afa1580156126f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061271b9190614c24565b9050919050565b61272a612aaa565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279090614cdf565b60405180910390fd5b6127a281612be0565b50565b606060006127c460026000858152602001908152602001600020612b3f565b905060008167ffffffffffffffff8111156127e2576127e1613562565b5b60405190808252806020026020018201604052801561281b57816020015b612808613240565b8152602001906001900390816128005790505b50905060005b828110156129d05760006128508260026000898152602001908152602001600020612b5490919063ffffffff16565b9050600460008281526020019081526020016000206040518060600160405290816000820154815260200160018201805461288a906145ea565b80601f01602080910402602001604051908101604052809291908181526020018280546128b6906145ea565b80156129035780601f106128d857610100808354040283529160200191612903565b820191906000526020600020905b8154815290600101906020018083116128e657829003601f168201915b5050505050815260200160028201805461291c906145ea565b80601f0160208091040260200160405190810160405280929190818152602001828054612948906145ea565b80156129955780601f1061296a57610100808354040283529160200191612995565b820191906000526020600020905b81548152906001019060200180831161297857829003601f168201915b5050505050815250508383815181106129b1576129b06144e5565b5b60200260200101819052505080806129c890614543565b915050612821565b508092505050919050565b6000612a3f84600260068111156129f5576129f4614411565b5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610c4d565b90509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600883901c9050600060ff84166001901b9050600081866000016000858152602001908152602001600020541614159250505092915050565b612ab2612d16565b73ffffffffffffffffffffffffffffffffffffffff16612ad061148e565b73ffffffffffffffffffffffffffffffffffffffff1614612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d90614d4b565b60405180910390fd5b565b600082612b358584612d1e565b1490509392505050565b6000612b4d82600001612d74565b9050919050565b6000612b638360000183612d85565b60001c905092915050565b6000612b80836000018360001b612db0565b905092915050565b6000612b9a836000018360001b612dd3565b905092915050565b6000600882901c9050600060ff83166001901b9050808460000160008481526020019081526020016000206000828254179250508190555050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082612cb2868685612ee7565b149050949350505050565b6000600882901c9050600060ff83166001901b905080198460000160008481526020019081526020016000206000828254169250508190555050505050565b6000612d0e836000018360001b61318e565b905092915050565b600033905090565b60008082905060005b8451811015612d6957612d5482868381518110612d4757612d466144e5565b5b60200260200101516131fe565b91508080612d6190614543565b915050612d27565b508091505092915050565b600081600001805490509050919050565b6000826000018281548110612d9d57612d9c6144e5565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612edb576000600182612e059190614d6b565b9050600060018660000180549050612e1d9190614d6b565b9050818114612e8c576000866000018281548110612e3e57612e3d6144e5565b5b9060005260206000200154905080876000018481548110612e6257612e616144e5565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612ea057612e9f614d9f565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ee1565b60009150505b92915050565b60008082519050600084519050806001875184612f049190614b80565b612f0e9190614d6b565b14612f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4590614e1a565b60405180910390fd5b60008167ffffffffffffffff811115612f6a57612f69613562565b5b604051908082528060200260200182016040528015612f985781602001602082028036833780820191505090505b5090506000806000805b858110156130f2576000878510612fdf57858480612fbf90614543565b955081518110612fd257612fd16144e5565b5b6020026020010151613007565b898580612feb90614543565b965081518110612ffe57612ffd6144e5565b5b60200260200101515b905060008b838151811061301e5761301d6144e5565b5b6020026020010151613056578c848061303690614543565b955081518110613049576130486144e5565b5b60200260200101516130b2565b8886106130895786858061306990614543565b96508151811061307c5761307b6144e5565b5b60200260200101516130b1565b8a868061309590614543565b9750815181106130a8576130a76144e5565b5b60200260200101515b5b90506130be82826131fe565b8784815181106130d1576130d06144e5565b5b602002602001018181525050505080806130ea90614543565b915050612fa2565b506000851115613130578360018661310a9190614d6b565b8151811061311b5761311a6144e5565b5b60200260200101519650505050505050613187565b6000861115613162578760008151811061314d5761314c6144e5565b5b60200260200101519650505050505050613187565b89600081518110613176576131756144e5565b5b602002602001015196505050505050505b9392505050565b600061319a8383612db0565b6131f35782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506131f8565b600090505b92915050565b6000818310613216576132118284613229565b613221565b6132208383613229565b5b905092915050565b600082600052816020526040600020905092915050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61328881613275565b811461329357600080fd5b50565b6000813590506132a58161327f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006132d6826132ab565b9050919050565b6132e6816132cb565b81146132f157600080fd5b50565b600081359050613303816132dd565b92915050565b600080604083850312156133205761331f61326b565b5b600061332e85828601613296565b925050602061333f858286016132f4565b9150509250929050565b60008115159050919050565b61335e81613349565b82525050565b60006020820190506133796000830184613355565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133a4576133a361337f565b5b8235905067ffffffffffffffff8111156133c1576133c0613384565b5b6020830191508360018202830111156133dd576133dc613389565b5b9250929050565b600080600080600060808688031215613400576133ff61326b565b5b600061340e88828901613296565b955050602061341f88828901613296565b945050604086013567ffffffffffffffff8111156134405761343f613270565b5b61344c8882890161338e565b9350935050606061345f88828901613296565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6134a181613349565b82525050565b60006134b38383613498565b60208301905092915050565b6000602082019050919050565b60006134d78261346c565b6134e18185613477565b93506134ec83613488565b8060005b8381101561351d57815161350488826134a7565b975061350f836134bf565b9250506001810190506134f0565b5085935050505092915050565b6000602082019050818103600083015261354481846134cc565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61359a82613551565b810181811067ffffffffffffffff821117156135b9576135b8613562565b5b80604052505050565b60006135cc613261565b90506135d88282613591565b919050565b600067ffffffffffffffff8211156135f8576135f7613562565b5b61360182613551565b9050602081019050919050565b82818337600083830152505050565b600061363061362b846135dd565b6135c2565b90508281526020810184848401111561364c5761364b61354c565b5b61365784828561360e565b509392505050565b600082601f8301126136745761367361337f565b5b813561368484826020860161361d565b91505092915050565b600080604083850312156136a4576136a361326b565b5b60006136b285828601613296565b925050602083013567ffffffffffffffff8111156136d3576136d2613270565b5b6136df8582860161365f565b9150509250929050565b6136f281613275565b82525050565b600060208201905061370d60008301846136e9565b92915050565b60008083601f8401126137295761372861337f565b5b8235905067ffffffffffffffff81111561374657613745613384565b5b60208301915083602082028301111561376257613761613389565b5b9250929050565b600080600080606085870312156137835761378261326b565b5b600061379187828801613296565b94505060206137a2878288016132f4565b935050604085013567ffffffffffffffff8111156137c3576137c2613270565b5b6137cf87828801613713565b925092505092959194509250565b6000602082840312156137f3576137f261326b565b5b6000613801848285016132f4565b91505092915050565b6000602082840312156138205761381f61326b565b5b600061382e84828501613296565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613871578082015181840152602081019050613856565b60008484015250505050565b600061388882613837565b6138928185613842565b93506138a2818560208601613853565b6138ab81613551565b840191505092915050565b60006060820190506138cb60008301866136e9565b81810360208301526138dd818561387d565b905081810360408301526138f1818461387d565b9050949350505050565b600067ffffffffffffffff82111561391657613915613562565b5b602082029050602081019050919050565b6000819050919050565b61393a81613927565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600061397061396b846138fb565b6135c2565b9050808382526020820190506020840283018581111561399357613992613389565b5b835b818110156139bc57806139a88882613948565b845260208401935050602081019050613995565b5050509392505050565b600082601f8301126139db576139da61337f565b5b81356139eb84826020860161395d565b91505092915050565b60008060008060808587031215613a0e57613a0d61326b565b5b6000613a1c87828801613296565b9450506020613a2d87828801613296565b935050604085013567ffffffffffffffff811115613a4e57613a4d613270565b5b613a5a878288016139c6565b9250506060613a6b87828801613948565b91505092959194509250565b600080600060408486031215613a9057613a8f61326b565b5b6000613a9e86828701613296565b935050602084013567ffffffffffffffff811115613abf57613abe613270565b5b613acb8682870161338e565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613b0c81613275565b82525050565b6000613b1e8383613b03565b60208301905092915050565b6000602082019050919050565b6000613b4282613ad7565b613b4c8185613ae2565b9350613b5783613af3565b8060005b83811015613b88578151613b6f8882613b12565b9750613b7a83613b2a565b925050600181019050613b5b565b5085935050505092915050565b60006020820190508181036000830152613baf8184613b37565b905092915050565b600080600060608486031215613bd057613bcf61326b565b5b6000613bde86828701613296565b9350506020613bef86828701613296565b925050604084013567ffffffffffffffff811115613c1057613c0f613270565b5b613c1c8682870161365f565b9150509250925092565b600080600060608486031215613c3f57613c3e61326b565b5b6000613c4d86828701613296565b9350506020613c5e86828701613296565b9250506040613c6f86828701613948565b9150509250925092565b600067ffffffffffffffff821115613c9457613c93613562565b5b602082029050602081019050919050565b613cae81613349565b8114613cb957600080fd5b50565b600081359050613ccb81613ca5565b92915050565b6000613ce4613cdf84613c79565b6135c2565b90508083825260208201905060208402830185811115613d0757613d06613389565b5b835b81811015613d305780613d1c8882613cbc565b845260208401935050602081019050613d09565b5050509392505050565b600082601f830112613d4f57613d4e61337f565b5b8135613d5f848260208601613cd1565b91505092915050565b600080600080600060a08688031215613d8457613d8361326b565b5b6000613d9288828901613296565b9550506020613da388828901613296565b945050604086013567ffffffffffffffff811115613dc457613dc3613270565b5b613dd0888289016139c6565b935050606086013567ffffffffffffffff811115613df157613df0613270565b5b613dfd88828901613d3a565b925050608086013567ffffffffffffffff811115613e1e57613e1d613270565b5b613e2a888289016139c6565b9150509295509295909350565b600080600080600060608688031215613e5357613e5261326b565b5b6000613e6188828901613296565b955050602086013567ffffffffffffffff811115613e8257613e81613270565b5b613e8e8882890161338e565b9450945050604086013567ffffffffffffffff811115613eb157613eb0613270565b5b613ebd88828901613713565b92509250509295509295909350565b613ed5816132cb565b82525050565b6000602082019050613ef06000830184613ecc565b92915050565b600080fd5b600080fd5b600060608284031215613f1657613f15613ef6565b5b613f2060606135c2565b90506000613f3084828501613296565b600083015250602082013567ffffffffffffffff811115613f5457613f53613efb565b5b613f608482850161365f565b602083015250604082013567ffffffffffffffff811115613f8457613f83613efb565b5b613f908482850161365f565b60408301525092915050565b60008060008060608587031215613fb657613fb561326b565b5b6000613fc487828801613296565b945050602085013567ffffffffffffffff811115613fe557613fe4613270565b5b613ff187828801613f00565b935050604085013567ffffffffffffffff81111561401257614011613270565b5b61401e87828801613713565b925092505092959194509250565b60006020820190508181036000830152614046818461387d565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614083816132cb565b82525050565b6000614095838361407a565b60208301905092915050565b6000602082019050919050565b60006140b98261404e565b6140c38185614059565b93506140ce8361406a565b8060005b838110156140ff5781516140e68882614089565b97506140f1836140a1565b9250506001810190506140d2565b5085935050505092915050565b6000602082019050818103600083015261412681846140ae565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061417682613837565b614180818561415a565b9350614190818560208601613853565b61419981613551565b840191505092915050565b60006141b0838361416b565b905092915050565b6000602082019050919050565b60006141d08261412e565b6141da8185614139565b9350836020820285016141ec8561414a565b8060005b85811015614228578484038952815161420985826141a4565b9450614214836141b8565b925060208a019950506001810190506141f0565b50829750879550505050505092915050565b6000602082019050818103600083015261425481846141c5565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006060830160008301516142a06000860182613b03565b50602083015184820360208601526142b8828261416b565b915050604083015184820360408601526142d2828261416b565b9150508091505092915050565b60006142eb8383614288565b905092915050565b6000602082019050919050565b600061430b8261425c565b6143158185614267565b93508360208202850161432785614278565b8060005b85811015614363578484038952815161434485826142df565b945061434f836142f3565b925060208a0199505060018101905061432b565b50829750879550505050505092915050565b6000602082019050818103600083015261438f8184614300565b905092915050565b6000819050919050565b60006143bc6143b76143b2846132ab565b614397565b6132ab565b9050919050565b60006143ce826143a1565b9050919050565b60006143e0826143c3565b9050919050565b6143f0816143d5565b82525050565b600060208201905061440b60008301846143e7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60008160601b9050919050565b600061445882614440565b9050919050565b600061446a8261444d565b9050919050565b61448261447d826132cb565b61445f565b82525050565b60006144948284614471565b60148201915081905092915050565b6000815190506144b2816132dd565b92915050565b6000602082840312156144ce576144cd61326b565b5b60006144dc848285016144a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061454e82613275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145805761457f614514565b5b600182019050919050565b60006040820190506145a060008301856136e9565b81810360208301526145b2818461387d565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061460257607f821691505b602082108103614615576146146145bb565b5b50919050565b600082825260208201905092915050565b7f4e6f7420504b50204e4654206f776e6572000000000000000000000000000000600082015250565b600061466260118361461b565b915061466d8261462c565b602082019050919050565b6000602082019050818103600083015261469181614655565b9050919050565b6146a181613927565b82525050565b60006020820190506146bc6000830184614698565b92915050565b60006146ce8385613842565b93506146db83858461360e565b6146e483613551565b840190509392505050565b600060608201905061470460008301876136e9565b81810360208301526147178185876146c2565b905061472660408301846136e9565b95945050505050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461475c816145ea565b614766818661472f565b945060018216600081146147815760018114614796576147c9565b60ff19831686528115158202860193506147c9565b61479f8561473a565b60005b838110156147c1578154818901526001820191506020810190506147a2565b838801955050505b50505092915050565b60006147de828461474f565b915081905092915050565b7f43616e6e6f7420616464206120646966666572656e74207075626b657920666f60008201527f72207468652073616d652061757468206d6574686f64207479706520616e642060208201527f6964000000000000000000000000000000000000000000000000000000000000604082015250565b600061486b60428361461b565b9150614876826147e9565b606082019050919050565b6000602082019050818103600083015261489a8161485e565b9050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826148b1565b6148f886836148b1565b95508019841693508086168417925050509392505050565b600061492b61492661492184613275565b614397565b613275565b9050919050565b6000819050919050565b61494583614910565b61495961495182614932565b8484546148be565b825550505050565b600090565b61496e614961565b61497981848461493c565b505050565b5b8181101561499d57614992600082614966565b60018101905061497f565b5050565b601f8211156149e2576149b38161473a565b6149bc846148a1565b810160208510156149cb578190505b6149df6149d7856148a1565b83018261497e565b50505b505050565b600082821c905092915050565b6000614a05600019846008026149e7565b1980831691505092915050565b6000614a1e83836149f4565b9150826002028217905092915050565b614a3782613837565b67ffffffffffffffff811115614a5057614a4f613562565b5b614a5a82546145ea565b614a658282856149a1565b600060209050601f831160018114614a985760008415614a86578287015190505b614a908582614a12565b865550614af8565b601f198416614aa68661473a565b60005b82811015614ace57848901518255600182019150602085019450602081019050614aa9565b86831015614aeb5784890151614ae7601f8916826149f4565b8355505b6001600288020188555050505b505050505050565b6000606082019050614b1560008301866136e9565b8181036020830152614b27818561387d565b9050614b3660408301846136e9565b949350505050565b600081519050614b4d81613ca5565b92915050565b600060208284031215614b6957614b6861326b565b5b6000614b7784828501614b3e565b91505092915050565b6000614b8b82613275565b9150614b9683613275565b9250828201905080821115614bae57614bad614514565b5b92915050565b6000614bc7614bc2846135dd565b6135c2565b905082815260208101848484011115614be357614be261354c565b5b614bee848285613853565b509392505050565b600082601f830112614c0b57614c0a61337f565b5b8151614c1b848260208601614bb4565b91505092915050565b600060208284031215614c3a57614c3961326b565b5b600082015167ffffffffffffffff811115614c5857614c57613270565b5b614c6484828501614bf6565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614cc960268361461b565b9150614cd482614c6d565b604082019050919050565b60006020820190508181036000830152614cf881614cbc565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d3560208361461b565b9150614d4082614cff565b602082019050919050565b60006020820190508181036000830152614d6481614d28565b9050919050565b6000614d7682613275565b9150614d8183613275565b9250828203905081811115614d9957614d98614514565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4d65726b6c6550726f6f663a20696e76616c6964206d756c746970726f6f6600600082015250565b6000614e04601f8361461b565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b905091905056fea264697066735822122097f120614501882fa47939caed2da0c057e01242fb93eb22f1f7662fb5cf27e464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"userPubkey","type":"bytes"}],"name":"PermittedAuthMethodAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"}],"name":"PermittedAuthMethodRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authMethodType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"id","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"PermittedAuthMethodScopeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"group","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootHashUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod","name":"authMethod","type":"tuple"},{"internalType":"uint256[]","name":"scopes","type":"uint256[]"}],"name":"addPermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"addPermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"authMethods","outputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getAuthMethodId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedActions","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"maxScopeId","type":"uint256"}],"name":"getPermittedAuthMethodScopes","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPermittedAuthMethods","outputs":[{"components":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"bytes","name":"userPubkey","type":"bytes"}],"internalType":"struct PKPPermissions.AuthMethod[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getTokenIdsForAuthMethod","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"getUserPubkeyForAuthMethod","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"isPermittedAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isPermittedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"isPermittedAuthMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"isPermittedAuthMethodScopePresent","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":"pkpNFT","outputs":[{"internalType":"contract PKPNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"removePermittedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"removePermittedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"}],"name":"removePermittedAuthMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"authMethodType","type":"uint256"},{"internalType":"bytes","name":"id","type":"bytes"},{"internalType":"uint256","name":"scopeId","type":"uint256"}],"name":"removePermittedAuthMethodScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verifyState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"group","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool[]","name":"proofFlags","type":"bool[]"},{"internalType":"bytes32[]","name":"leaves","type":"bytes32[]"}],"name":"verifyStates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/RateLimitNFT.json b/deployments/rolluptestnet_987/RateLimitNFT.json deleted file mode 100644 index 03000f0..0000000 --- a/deployments/rolluptestnet_987/RateLimitNFT.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/RateLimitNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/// @title Rate Limit NFT\\n///\\n/// @dev This is the contract for the Rate Limit NFTs\\ncontract RateLimitNFT is\\n ERC721(\\\"Rate Limit Increases on Lit Protocol\\\", \\\"RLI\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using Strings for uint256;\\n /* ========== STATE VARIABLES ========== */\\n\\n address public freeMintSigner;\\n uint256 public additionalRequestsPerMillisecondCost;\\n uint256 public tokenIdCounter;\\n uint256 public defaultRateLimitWindowMilliseconds = 60 * 60 * 1000; // 60 mins\\n uint256 public RLIHolderRateLimitWindowMilliseconds = 5 * 60 * 1000; // 5 mins\\n uint256 public freeRequestsPerRateLimitWindow = 10;\\n\\n mapping(uint256 => RateLimit) public capacity;\\n mapping(bytes32 => bool) public redeemedFreeMints;\\n\\n struct RateLimit {\\n uint256 requestsPerMillisecond;\\n uint256 expiresAt;\\n }\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n additionalRequestsPerMillisecondCost = 1; // 1 wei\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 expiresAt,\\n uint256 requestsPerMillisecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n // make sure the msgHash matches the tokenId\\n // if these don't match, the user could use any old signature\\n // to mint any number of PKPs\\n // and this would be vulnerable to replay attacks\\n // FIXME this needs the whole \\\"ethereum signed message: \\\\27\\\" thingy prepended to actually work\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(expiresAt, requestsPerMillisecond))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the expiresAt + requestsPerMillisecond. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // make sure it hasn't already been redeemed\\n require(\\n !redeemedFreeMints[msgHash],\\n \\\"This freeMint has already been redeemed. How embarassing.\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function calculateCost(uint256 requestsPerMillisecond, uint256 expiresAt)\\n public\\n view\\n returns (uint256)\\n {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInMilliseconds = (expiresAt - block.timestamp) * 1000;\\n\\n // calculate the cost\\n uint256 cost = requestsPerMillisecond *\\n durationInMilliseconds *\\n additionalRequestsPerMillisecondCost;\\n\\n return cost;\\n }\\n\\n function calculateRequestsPerSecond(uint256 payingAmount, uint256 expiresAt)\\n public\\n view\\n returns (uint256)\\n {\\n require(\\n expiresAt > block.timestamp,\\n \\\"The expiresAt must be in the future\\\"\\n );\\n\\n // calculate the duration\\n uint256 durationInMilliseconds = (expiresAt - block.timestamp) * 1000;\\n\\n // calculate the cost\\n uint256 requestsPerSecond = payingAmount /\\n (durationInMilliseconds * additionalRequestsPerMillisecondCost);\\n\\n return requestsPerSecond;\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit Protocol Rate Limit Increase\\\", \\\"description\\\": \\\"This NFT entitles the holder to a rate limit increase on the Lit Protocol Network\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"display_type\\\": \\\"date\\\", \\\"trait_type\\\": \\\"Expiration Date\\\", \\\"value\\\": ',\\n capacity[tokenId].expiresAt.toString(),\\n '}, {\\\"display_type\\\": \\\"number\\\", \\\"trait_type\\\": \\\"Requests Per Millisecond\\\", \\\"value\\\": ',\\n capacity[tokenId].requestsPerMillisecond.toString(),\\n \\\"}]}\\\"\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n\\n function isExpired(uint256 tokenId) public view returns (bool) {\\n return capacity[tokenId].expiresAt <= block.timestamp;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// mint a token with a certain number of requests per millisecond and a certain expiration time. Requests per second is calculated from the msg.value amount. You can find out the cost for a certain requests per second value by using the calculateCost() function.\\n function mint(uint256 expiresAt) public payable {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n uint256 requestsPerMillisecond = calculateRequestsPerSecond(\\n msg.value,\\n expiresAt\\n );\\n\\n // sanity check\\n uint256 cost = calculateCost(requestsPerMillisecond, expiresAt);\\n require(\\n msg.value > 0 && msg.value >= cost,\\n \\\"You must send the cost of this rate limit increase. To check the cost, use the calculateCost function.\\\"\\n );\\n\\n _mintWithoutValueCheck(tokenId, requestsPerMillisecond, expiresAt);\\n }\\n\\n function freeMint(\\n uint256 expiresAt,\\n uint256 requestsPerMillisecond,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public {\\n tokenIdCounter++;\\n uint256 tokenId = tokenIdCounter;\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(expiresAt, requestsPerMillisecond, msgHash, v, r, s);\\n redeemedFreeMints[msgHash] = true;\\n\\n _mintWithoutValueCheck(tokenId, requestsPerMillisecond, expiresAt);\\n }\\n\\n function _mintWithoutValueCheck(\\n uint256 tokenId,\\n uint256 requestsPerMillisecond,\\n uint256 expiresAt\\n ) internal {\\n _safeMint(msg.sender, tokenId);\\n capacity[tokenId] = RateLimit(requestsPerMillisecond, expiresAt);\\n }\\n\\n function setAdditionalRequestsPerSecondCost(\\n uint256 newAdditionalRequestsPerMillisecondCost\\n ) public onlyOwner {\\n additionalRequestsPerMillisecondCost = newAdditionalRequestsPerMillisecondCost;\\n emit AdditionalRequestsPerSecondCostSet(\\n newAdditionalRequestsPerMillisecondCost\\n );\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n function setRateLimitWindowMilliseconds(\\n uint256 newRateLimitWindowMilliseconds\\n ) public onlyOwner {\\n defaultRateLimitWindowMilliseconds = newRateLimitWindowMilliseconds;\\n emit RateLimitWindowMillisecondsSet(newRateLimitWindowMilliseconds);\\n }\\n\\n function setRLIHolderRateLimitWindowMilliseconds(\\n uint256 newRLIHolderRateLimitWindowMilliseconds\\n ) public onlyOwner {\\n RLIHolderRateLimitWindowMilliseconds = newRLIHolderRateLimitWindowMilliseconds;\\n emit RLIHolderRateLimitWindowMillisecondsSet(\\n newRLIHolderRateLimitWindowMilliseconds\\n );\\n }\\n\\n function setFreeRequestsPerRateLimitWindow(\\n uint256 newFreeRequestsPerRateLimitWindow\\n ) public onlyOwner {\\n freeRequestsPerRateLimitWindow = newFreeRequestsPerRateLimitWindow;\\n emit FreeRequestsPerRateLimitWindowSet(\\n newFreeRequestsPerRateLimitWindow\\n );\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event AdditionalRequestsPerSecondCostSet(\\n uint256 newAdditionalRequestsPerMillisecondCost\\n );\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event RateLimitWindowMillisecondsSet(\\n uint256 newRateLimitWindowMilliseconds\\n );\\n event RLIHolderRateLimitWindowMillisecondsSet(\\n uint256 newRLIHolderRateLimitWindowMilliseconds\\n );\\n event FreeRequestsPerRateLimitWindowSet(\\n uint256 newFreeRequestsPerRateLimitWindow\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x0646bD00Dfb8D1bd83562e6E5A2cF066f083986A","bytecode":"0x60806040526236ee80600f55620493e0601055600a6011553480156200002457600080fd5b506040518060600160405280602481526020016200543e602491396040518060400160405280600381526020017f524c490000000000000000000000000000000000000000000000000000000000815250816000908162000086919062000419565b50806001908162000098919062000419565b505050620000bb620000af620000d160201b60201c565b620000d960201b60201c565b6001600b819055506001600d8190555062000500565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200022157607f821691505b602082108103620002375762000236620001d9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000262565b620002ad868362000262565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002fa620002f4620002ee84620002c5565b620002cf565b620002c5565b9050919050565b6000819050919050565b6200031683620002d9565b6200032e620003258262000301565b8484546200026f565b825550505050565b600090565b6200034562000336565b620003528184846200030b565b505050565b5b818110156200037a576200036e6000826200033b565b60018101905062000358565b5050565b601f821115620003c95762000393816200023d565b6200039e8462000252565b81016020851015620003ae578190505b620003c6620003bd8562000252565b83018262000357565b50505b505050565b600082821c905092915050565b6000620003ee60001984600802620003ce565b1980831691505092915050565b6000620004098383620003db565b9150826002028217905092915050565b62000424826200019f565b67ffffffffffffffff81111562000440576200043f620001aa565b5b6200044c825462000208565b620004598282856200037e565b600060209050601f8311600181146200049157600084156200047c578287015190505b620004888582620003fb565b865550620004f8565b601f198416620004a1866200023d565b60005b82811015620004cb57848901518255600182019150602085019450602081019050620004a4565b86831015620004eb5784890151620004e7601f891682620003db565b8355505b6001600288020188555050505b505050505050565b614f2e80620005106000396000f3fe6080604052600436106102465760003560e01c80636352211e11610139578063a0712d68116100b6578063c87b56dd1161007a578063c87b56dd14610890578063ce394696146108cd578063d9548e531461090a578063e985e9c514610947578063f2fde38b14610984578063faea717c146109ad57610246565b8063a0712d68146107b9578063a22cb465146107d5578063ab1bbeca146107fe578063b88d4fde1461083c578063b94a21021461086557610246565b80638da5cb5b116100fd5780638da5cb5b146106e657806395d89b411461071157806398bdf6f51461073c578063995eebab146107675780639fadb6431461079057610246565b80636352211e146106015780636a8e29ed1461063e57806370a0823114610667578063715018a6146106a45780638c8e3c84146106bb57610246565b80632f745c59116101c75780634116b8931161018b5780634116b8931461050a57806342842e0e1461054757806342966c681461057057806345ca8a7a146105995780634f6ccce7146105c457610246565b80632f745c59146104275780633488ab13146104645780633b1898521461048d5780633b1a72cc146104b65780633ccfd60b146104f357610246565b80631f2757131161020e5780631f2757131461034457806320fef3df1461038157806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806318160ddd14610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190612f45565b6109d8565b60405161027f9190612f8d565b60405180910390f35b34801561029457600080fd5b5061029d610b12565b6040516102aa9190613038565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d59190613090565b610ba4565b6040516102e791906130fe565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613145565b610bea565b005b34801561032557600080fd5b5061032e610d01565b60405161033b9190613194565b60405180910390f35b34801561035057600080fd5b5061036b600480360381019061036691906131e5565b610d0e565b6040516103789190613221565b60405180910390f35b34801561038d57600080fd5b506103a860048036038101906103a39190613090565b610d3e565b005b3480156103b657600080fd5b506103d160048036038101906103cc919061323c565b610d87565b005b3480156103df57600080fd5b506103e8610de7565b6040516103f59190613194565b60405180910390f35b34801561040a57600080fd5b5061042560048036038101906104209190613090565b610ded565b005b34801561043357600080fd5b5061044e60048036038101906104499190613145565b610e36565b60405161045b9190613194565b60405180910390f35b34801561047057600080fd5b5061048b600480360381019061048691906132c8565b610edb565b005b34801561049957600080fd5b506104b460048036038101906104af9190613355565b6110a0565b005b3480156104c257600080fd5b506104dd60048036038101906104d891906131e5565b61112f565b6040516104ea9190612f8d565b60405180910390f35b3480156104ff57600080fd5b5061050861114f565b005b34801561051657600080fd5b50610531600480360381019061052c9190613382565b611262565b60405161053e9190613194565b60405180910390f35b34801561055357600080fd5b5061056e6004803603810190610569919061323c565b6112eb565b005b34801561057c57600080fd5b5061059760048036038101906105929190613090565b61130b565b005b3480156105a557600080fd5b506105ae611367565b6040516105bb9190613194565b60405180910390f35b3480156105d057600080fd5b506105eb60048036038101906105e69190613090565b61136d565b6040516105f89190613194565b60405180910390f35b34801561060d57600080fd5b5061062860048036038101906106239190613090565b6113de565b60405161063591906130fe565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190613090565b61148f565b005b34801561067357600080fd5b5061068e60048036038101906106899190613355565b6114d8565b60405161069b9190613194565b60405180910390f35b3480156106b057600080fd5b506106b961158f565b005b3480156106c757600080fd5b506106d06115a3565b6040516106dd9190613194565b60405180910390f35b3480156106f257600080fd5b506106fb6115a9565b60405161070891906130fe565b60405180910390f35b34801561071d57600080fd5b506107266115d3565b6040516107339190613038565b60405180910390f35b34801561074857600080fd5b50610751611665565b60405161075e9190613194565b60405180910390f35b34801561077357600080fd5b5061078e600480360381019061078991906132c8565b61166b565b005b34801561079c57600080fd5b506107b760048036038101906107b29190613090565b6116d8565b005b6107d360048036038101906107ce9190613090565b611721565b005b3480156107e157600080fd5b506107fc60048036038101906107f791906133ee565b6117bc565b005b34801561080a57600080fd5b5061082560048036038101906108209190613090565b6117d2565b60405161083392919061342e565b60405180910390f35b34801561084857600080fd5b50610863600480360381019061085e919061358c565b6117f6565b005b34801561087157600080fd5b5061087a611858565b60405161088791906130fe565b60405180910390f35b34801561089c57600080fd5b506108b760048036038101906108b29190613090565b61187e565b6040516108c49190613038565b60405180910390f35b3480156108d957600080fd5b506108f460048036038101906108ef9190613382565b611935565b6040516109019190613194565b60405180910390f35b34801561091657600080fd5b50610931600480360381019061092c9190613090565b6119be565b60405161093e9190612f8d565b60405180910390f35b34801561095357600080fd5b5061096e6004803603810190610969919061360f565b6119e1565b60405161097b9190612f8d565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a69190613355565b611a75565b005b3480156109b957600080fd5b506109c2611af8565b6040516109cf9190613194565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b0b57507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b219061367e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4d9061367e565b8015610b9a5780601f10610b6f57610100808354040283529160200191610b9a565b820191906000526020600020905b815481529060010190602001808311610b7d57829003601f168201915b5050505050905090565b6000610baf82611afe565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bf5826113de565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5c90613721565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c84611b49565b73ffffffffffffffffffffffffffffffffffffffff161480610cb35750610cb281610cad611b49565b6119e1565b5b610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce9906137b3565b60405180910390fd5b610cfc8383611b51565b505050565b6000600980549050905090565b600081604051602001610d21919061384b565b604051602081830303815290604052805190602001209050919050565b610d46611c0a565b806010819055507fc9f68d4642b75238a09de01fc991dbaecb731624b8246a79f6bddfb265ab9c6581604051610d7c9190613194565b60405180910390a150565b610d98610d92611b49565b82611c88565b610dd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dce906138e3565b60405180910390fd5b610de2838383611d1d565b505050565b60115481565b610df5611c0a565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e2b9190613194565b60405180910390a150565b6000610e41836114d8565b8210610e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7990613975565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f0e8787604051602001610ef39291906139b6565b60405160208183030381529060405280519060200120610d0e565b9050848114610f52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4990613a7a565b60405180910390fd5b600060018686868660405160008152602001604052604051610f779493929190613aa9565b6020604051602081039080840390855afa158015610f99573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102c90613b86565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff1615611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108d90613c18565b60405180910390fd5b5050505050505050565b6110a8611c0a565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b611157611c0a565b6002600b540361119c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119390613c84565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff16826040516111cf90613cd5565b60006040518083038185875af1925050503d806000811461120c576040519150601f19603f3d011682016040523d82523d6000602084013e611211565b606091505b505090508061121f57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a232518260405161124e9190613194565b60405180910390a150506001600b81905550565b60004282116112a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129d90613d5c565b60405180910390fd5b60006103e842846112b79190613dab565b6112c19190613ddf565b90506000600d54826112d39190613ddf565b856112de9190613e50565b9050809250505092915050565b611306838383604051806020016040528060008152506117f6565b505050565b61131c611316611b49565b82611c88565b61135b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611352906138e3565b60405180910390fd5b61136481611f83565b50565b600f5481565b6000611377610d01565b82106113b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113af90613ef3565b60405180910390fd5b600982815481106113cc576113cb613f13565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611486576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147d90613f8e565b60405180910390fd5b80915050919050565b611497611c0a565b80600f819055507f48e50e8ecbfe9fa83d92fd45f81b044a22e6a14ab3bfbef5c58ae2f80b796fca816040516114cd9190613194565b60405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f90614020565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611597611c0a565b6115a160006120a0565b565b600d5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115e29061367e565b80601f016020809104026020016040519081016040528092919081815260200182805461160e9061367e565b801561165b5780601f106116305761010080835404028352916020019161165b565b820191906000526020600020905b81548152906001019060200180831161163e57829003601f168201915b5050505050905090565b600e5481565b600e600081548092919061167e90614040565b91905055506000600e549050611698878787878787610edb565b60016013600087815260200190815260200160002060006101000a81548160ff0219169083151502179055506116cf818789612166565b50505050505050565b6116e0611c0a565b80600d819055507f6812e5d5d18adf9e51779dd1b67eef3cc61fdd5ca0289fcf7daefb629fb24974816040516117169190613194565b60405180910390a150565b600e600081548092919061173490614040565b91905055506000600e549050600061174c3484611262565b9050600061175a8285611935565b905060003411801561176c5750803410155b6117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a290614146565b60405180910390fd5b6117b6838386612166565b50505050565b6117ce6117c7611b49565b83836121b4565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b611807611801611b49565b83611c88565b611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d906138e3565b60405180910390fd5b61185284848484612320565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060006040518061048001604052806104568152602001614a6361045691399050600061190a826118c5601260008881526020019081526020016000206001015461237c565b6118e4601260008981526020019081526020016000206000015461237c565b6040516020016118f693929190614433565b6040516020818303038152906040526124dc565b90508060405160200161191d91906144dc565b60405160208183030381529060405292505050919050565b6000428211611979576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197090613d5c565b60405180910390fd5b60006103e8428461198a9190613dab565b6119949190613ddf565b90506000600d5482866119a79190613ddf565b6119b19190613ddf565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611a7d611c0a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae390614570565b60405180910390fd5b611af5816120a0565b50565b60105481565b611b078161263f565b611b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3d90613f8e565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611bc4836113de565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611c12611b49565b73ffffffffffffffffffffffffffffffffffffffff16611c306115a9565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d906145dc565b60405180910390fd5b565b600080611c94836113de565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611cd65750611cd581856119e1565b5b80611d1457508373ffffffffffffffffffffffffffffffffffffffff16611cfc84610ba4565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611d3d826113de565b73ffffffffffffffffffffffffffffffffffffffff1614611d93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8a9061466e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df990614700565b60405180910390fd5b611e0d8383836126ab565b611e18600082611b51565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e689190613dab565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ebf9190614720565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f7e8383836126bb565b505050565b6000611f8e826113de565b9050611f9c816000846126ab565b611fa7600083611b51565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ff79190613dab565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461209c816000846126bb565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61217033846126c0565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612222576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612219906147a0565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123139190612f8d565b60405180910390a3505050565b61232b848484611d1d565b612337848484846126de565b612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236d90614832565b60405180910390fd5b50505050565b6060600082036123c3576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506124d7565b600082905060005b600082146123f55780806123de90614040565b915050600a826123ee9190613e50565b91506123cb565b60008167ffffffffffffffff81111561241157612410613461565b5b6040519080825280601f01601f1916602001820160405280156124435781602001600182028036833780820191505090505b5090505b600085146124d05760018261245c9190613dab565b9150600a8561246b9190614852565b60306124779190614720565b60f81b81838151811061248d5761248c613f13565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856124c99190613e50565b9450612447565b8093505050505b919050565b606060008251036124fe5760405180602001604052806000815250905061263a565b6000604051806060016040528060408152602001614eb9604091399050600060036002855161252d9190614720565b6125379190613e50565b60046125439190613ddf565b67ffffffffffffffff81111561255c5761255b613461565b5b6040519080825280601f01601f19166020018201604052801561258e5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156125fa576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061259f565b5050600386510660018114612616576002811461262957612631565b603d6001830353603d6002830353612631565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6126b6838383612865565b505050565b505050565b6126da828260405180602001604052806000815250612977565b5050565b60006126ff8473ffffffffffffffffffffffffffffffffffffffff166129d2565b15612858578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612728611b49565b8786866040518563ffffffff1660e01b815260040161274a94939291906148cd565b6020604051808303816000875af192505050801561278657506040513d601f19601f82011682018060405250810190612783919061492e565b60015b612808573d80600081146127b6576040519150601f19603f3d011682016040523d82523d6000602084013e6127bb565b606091505b506000815103612800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f790614832565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061285d565b600190505b949350505050565b6128708383836129f5565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036128b2576128ad816129fa565b6128f1565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128f0576128ef8382612a43565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129335761292e81612bb0565b612972565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612971576129708282612c81565b5b5b505050565b6129818383612d00565b61298e60008484846126de565b6129cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c490614832565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612a50846114d8565b612a5a9190613dab565b9050600060086000848152602001908152602001600020549050818114612b3f576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612bc49190613dab565b90506000600a6000848152602001908152602001600020549050600060098381548110612bf457612bf3613f13565b5b906000526020600020015490508060098381548110612c1657612c15613f13565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612c6557612c6461495b565b5b6001900381819060005260206000200160009055905550505050565b6000612c8c836114d8565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612d6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d66906149d6565b60405180910390fd5b612d788161263f565b15612db8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612daf90614a42565b60405180910390fd5b612dc4600083836126ab565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e149190614720565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ed5600083836126bb565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f2281612eed565b8114612f2d57600080fd5b50565b600081359050612f3f81612f19565b92915050565b600060208284031215612f5b57612f5a612ee3565b5b6000612f6984828501612f30565b91505092915050565b60008115159050919050565b612f8781612f72565b82525050565b6000602082019050612fa26000830184612f7e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612fe2578082015181840152602081019050612fc7565b60008484015250505050565b6000601f19601f8301169050919050565b600061300a82612fa8565b6130148185612fb3565b9350613024818560208601612fc4565b61302d81612fee565b840191505092915050565b600060208201905081810360008301526130528184612fff565b905092915050565b6000819050919050565b61306d8161305a565b811461307857600080fd5b50565b60008135905061308a81613064565b92915050565b6000602082840312156130a6576130a5612ee3565b5b60006130b48482850161307b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130e8826130bd565b9050919050565b6130f8816130dd565b82525050565b600060208201905061311360008301846130ef565b92915050565b613122816130dd565b811461312d57600080fd5b50565b60008135905061313f81613119565b92915050565b6000806040838503121561315c5761315b612ee3565b5b600061316a85828601613130565b925050602061317b8582860161307b565b9150509250929050565b61318e8161305a565b82525050565b60006020820190506131a96000830184613185565b92915050565b6000819050919050565b6131c2816131af565b81146131cd57600080fd5b50565b6000813590506131df816131b9565b92915050565b6000602082840312156131fb576131fa612ee3565b5b6000613209848285016131d0565b91505092915050565b61321b816131af565b82525050565b60006020820190506132366000830184613212565b92915050565b60008060006060848603121561325557613254612ee3565b5b600061326386828701613130565b935050602061327486828701613130565b92505060406132858682870161307b565b9150509250925092565b600060ff82169050919050565b6132a58161328f565b81146132b057600080fd5b50565b6000813590506132c28161329c565b92915050565b60008060008060008060c087890312156132e5576132e4612ee3565b5b60006132f389828a0161307b565b965050602061330489828a0161307b565b955050604061331589828a016131d0565b945050606061332689828a016132b3565b935050608061333789828a016131d0565b92505060a061334889828a016131d0565b9150509295509295509295565b60006020828403121561336b5761336a612ee3565b5b600061337984828501613130565b91505092915050565b6000806040838503121561339957613398612ee3565b5b60006133a78582860161307b565b92505060206133b88582860161307b565b9150509250929050565b6133cb81612f72565b81146133d657600080fd5b50565b6000813590506133e8816133c2565b92915050565b6000806040838503121561340557613404612ee3565b5b600061341385828601613130565b9250506020613424858286016133d9565b9150509250929050565b60006040820190506134436000830185613185565b6134506020830184613185565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61349982612fee565b810181811067ffffffffffffffff821117156134b8576134b7613461565b5b80604052505050565b60006134cb612ed9565b90506134d78282613490565b919050565b600067ffffffffffffffff8211156134f7576134f6613461565b5b61350082612fee565b9050602081019050919050565b82818337600083830152505050565b600061352f61352a846134dc565b6134c1565b90508281526020810184848401111561354b5761354a61345c565b5b61355684828561350d565b509392505050565b600082601f83011261357357613572613457565b5b813561358384826020860161351c565b91505092915050565b600080600080608085870312156135a6576135a5612ee3565b5b60006135b487828801613130565b94505060206135c587828801613130565b93505060406135d68782880161307b565b925050606085013567ffffffffffffffff8111156135f7576135f6612ee8565b5b6136038782880161355e565b91505092959194509250565b6000806040838503121561362657613625612ee3565b5b600061363485828601613130565b925050602061364585828601613130565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061369657607f821691505b6020821081036136a9576136a861364f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061370b602183612fb3565b9150613716826136af565b604082019050919050565b6000602082019050818103600083015261373a816136fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061379d603e83612fb3565b91506137a882613741565b604082019050919050565b600060208201905081810360008301526137cc81613790565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613814601c836137d3565b915061381f826137de565b601c82019050919050565b6000819050919050565b613845613840826131af565b61382a565b82525050565b600061385682613807565b91506138628284613834565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006138cd602e83612fb3565b91506138d882613871565b604082019050919050565b600060208201905081810360008301526138fc816138c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061395f602b83612fb3565b915061396a82613903565b604082019050919050565b6000602082019050818103600083015261398e81613952565b9050919050565b6000819050919050565b6139b06139ab8261305a565b613995565b82525050565b60006139c2828561399f565b6020820191506139d2828461399f565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724d696c6c6973656360208201527f6f6e642e20204578706c61696e20796f757273656c6621000000000000000000604082015250565b6000613a64605783612fb3565b9150613a6f826139e2565b606082019050919050565b60006020820190508181036000830152613a9381613a57565b9050919050565b613aa38161328f565b82525050565b6000608082019050613abe6000830187613212565b613acb6020830186613a9a565b613ad86040830185613212565b613ae56060830184613212565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613b70604183612fb3565b9150613b7b82613aee565b606082019050919050565b60006020820190508181036000830152613b9f81613b63565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613c02603a83612fb3565b9150613c0d82613ba6565b604082019050919050565b60006020820190508181036000830152613c3181613bf5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613c6e601f83612fb3565b9150613c7982613c38565b602082019050919050565b60006020820190508181036000830152613c9d81613c61565b9050919050565b600081905092915050565b50565b6000613cbf600083613ca4565b9150613cca82613caf565b600082019050919050565b6000613ce082613cb2565b9150819050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b6000613d46602383612fb3565b9150613d5182613cea565b604082019050919050565b60006020820190508181036000830152613d7581613d39565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613db68261305a565b9150613dc18361305a565b9250828203905081811115613dd957613dd8613d7c565b5b92915050565b6000613dea8261305a565b9150613df58361305a565b9250828202613e038161305a565b91508282048414831517613e1a57613e19613d7c565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e5b8261305a565b9150613e668361305a565b925082613e7657613e75613e21565b5b828204905092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613edd602c83612fb3565b9150613ee882613e81565b604082019050919050565b60006020820190508181036000830152613f0c81613ed0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613f78601883612fb3565b9150613f8382613f42565b602082019050919050565b60006020820190508181036000830152613fa781613f6b565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061400a602983612fb3565b915061401582613fae565b604082019050919050565b6000602082019050818103600083015261403981613ffd565b9050919050565b600061404b8261305a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361407d5761407c613d7c565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b6000614130606783612fb3565b915061413b82614088565b608082019050919050565b6000602082019050818103600083015261415f81614123565b9050919050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061423460a0836137d3565b915061423f82614166565b60a082019050919050565b600081519050919050565b60006142608261424a565b61426a8185613ca4565b935061427a818560208601612fc4565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b60006143086054836137d3565b915061431382614286565b605482019050919050565b600061432982612fa8565b61433381856137d3565b9350614343818560208601612fc4565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a2022526571756573747320506572204d696c6c697360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006143d16051836137d3565b91506143dc8261434f565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061441d6003836137d3565b9150614428826143e7565b600382019050919050565b600061443e82614227565b915061444a8286614255565b9150614455826142fb565b9150614461828561431e565b915061446c826143c4565b9150614478828461431e565b915061448382614410565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006144c6601d836137d3565b91506144d182614490565b601d82019050919050565b60006144e7826144b9565b91506144f3828461431e565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061455a602683612fb3565b9150614565826144fe565b604082019050919050565b600060208201905081810360008301526145898161454d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145c6602083612fb3565b91506145d182614590565b602082019050919050565b600060208201905081810360008301526145f5816145b9565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614658602583612fb3565b9150614663826145fc565b604082019050919050565b600060208201905081810360008301526146878161464b565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006146ea602483612fb3565b91506146f58261468e565b604082019050919050565b60006020820190508181036000830152614719816146dd565b9050919050565b600061472b8261305a565b91506147368361305a565b925082820190508082111561474e5761474d613d7c565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061478a601983612fb3565b915061479582614754565b602082019050919050565b600060208201905081810360008301526147b98161477d565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061481c603283612fb3565b9150614827826147c0565b604082019050919050565b6000602082019050818103600083015261484b8161480f565b9050919050565b600061485d8261305a565b91506148688361305a565b92508261487857614877613e21565b5b828206905092915050565b600082825260208201905092915050565b600061489f8261424a565b6148a98185614883565b93506148b9818560208601612fc4565b6148c281612fee565b840191505092915050565b60006080820190506148e260008301876130ef565b6148ef60208301866130ef565b6148fc6040830185613185565b818103606083015261490e8184614894565b905095945050505050565b60008151905061492881612f19565b92915050565b60006020828403121561494457614943612ee3565b5b600061495284828501614919565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006149c0602083612fb3565b91506149cb8261498a565b602082019050919050565b600060208201905081810360008301526149ef816149b3565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614a2c601c83612fb3565b9150614a37826149f6565b602082019050919050565b60006020820190508181036000830152614a5b81614a1f565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ad3a2a5fc856b8ef8ede76806528a646a1e3761d7694275fbb7f9c182ca3f5c864736f6c6343000811003352617465204c696d697420496e63726561736573206f6e204c69742050726f746f636f6c","deployedBytecode":"0x6080604052600436106102465760003560e01c80636352211e11610139578063a0712d68116100b6578063c87b56dd1161007a578063c87b56dd14610890578063ce394696146108cd578063d9548e531461090a578063e985e9c514610947578063f2fde38b14610984578063faea717c146109ad57610246565b8063a0712d68146107b9578063a22cb465146107d5578063ab1bbeca146107fe578063b88d4fde1461083c578063b94a21021461086557610246565b80638da5cb5b116100fd5780638da5cb5b146106e657806395d89b411461071157806398bdf6f51461073c578063995eebab146107675780639fadb6431461079057610246565b80636352211e146106015780636a8e29ed1461063e57806370a0823114610667578063715018a6146106a45780638c8e3c84146106bb57610246565b80632f745c59116101c75780634116b8931161018b5780634116b8931461050a57806342842e0e1461054757806342966c681461057057806345ca8a7a146105995780634f6ccce7146105c457610246565b80632f745c59146104275780633488ab13146104645780633b1898521461048d5780633b1a72cc146104b65780633ccfd60b146104f357610246565b80631f2757131161020e5780631f2757131461034457806320fef3df1461038157806323b872dd146103aa57806326894764146103d357806328b9b37c146103fe57610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f057806318160ddd14610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d9190612f45565b6109d8565b60405161027f9190612f8d565b60405180910390f35b34801561029457600080fd5b5061029d610b12565b6040516102aa9190613038565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d59190613090565b610ba4565b6040516102e791906130fe565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613145565b610bea565b005b34801561032557600080fd5b5061032e610d01565b60405161033b9190613194565b60405180910390f35b34801561035057600080fd5b5061036b600480360381019061036691906131e5565b610d0e565b6040516103789190613221565b60405180910390f35b34801561038d57600080fd5b506103a860048036038101906103a39190613090565b610d3e565b005b3480156103b657600080fd5b506103d160048036038101906103cc919061323c565b610d87565b005b3480156103df57600080fd5b506103e8610de7565b6040516103f59190613194565b60405180910390f35b34801561040a57600080fd5b5061042560048036038101906104209190613090565b610ded565b005b34801561043357600080fd5b5061044e60048036038101906104499190613145565b610e36565b60405161045b9190613194565b60405180910390f35b34801561047057600080fd5b5061048b600480360381019061048691906132c8565b610edb565b005b34801561049957600080fd5b506104b460048036038101906104af9190613355565b6110a0565b005b3480156104c257600080fd5b506104dd60048036038101906104d891906131e5565b61112f565b6040516104ea9190612f8d565b60405180910390f35b3480156104ff57600080fd5b5061050861114f565b005b34801561051657600080fd5b50610531600480360381019061052c9190613382565b611262565b60405161053e9190613194565b60405180910390f35b34801561055357600080fd5b5061056e6004803603810190610569919061323c565b6112eb565b005b34801561057c57600080fd5b5061059760048036038101906105929190613090565b61130b565b005b3480156105a557600080fd5b506105ae611367565b6040516105bb9190613194565b60405180910390f35b3480156105d057600080fd5b506105eb60048036038101906105e69190613090565b61136d565b6040516105f89190613194565b60405180910390f35b34801561060d57600080fd5b5061062860048036038101906106239190613090565b6113de565b60405161063591906130fe565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190613090565b61148f565b005b34801561067357600080fd5b5061068e60048036038101906106899190613355565b6114d8565b60405161069b9190613194565b60405180910390f35b3480156106b057600080fd5b506106b961158f565b005b3480156106c757600080fd5b506106d06115a3565b6040516106dd9190613194565b60405180910390f35b3480156106f257600080fd5b506106fb6115a9565b60405161070891906130fe565b60405180910390f35b34801561071d57600080fd5b506107266115d3565b6040516107339190613038565b60405180910390f35b34801561074857600080fd5b50610751611665565b60405161075e9190613194565b60405180910390f35b34801561077357600080fd5b5061078e600480360381019061078991906132c8565b61166b565b005b34801561079c57600080fd5b506107b760048036038101906107b29190613090565b6116d8565b005b6107d360048036038101906107ce9190613090565b611721565b005b3480156107e157600080fd5b506107fc60048036038101906107f791906133ee565b6117bc565b005b34801561080a57600080fd5b5061082560048036038101906108209190613090565b6117d2565b60405161083392919061342e565b60405180910390f35b34801561084857600080fd5b50610863600480360381019061085e919061358c565b6117f6565b005b34801561087157600080fd5b5061087a611858565b60405161088791906130fe565b60405180910390f35b34801561089c57600080fd5b506108b760048036038101906108b29190613090565b61187e565b6040516108c49190613038565b60405180910390f35b3480156108d957600080fd5b506108f460048036038101906108ef9190613382565b611935565b6040516109019190613194565b60405180910390f35b34801561091657600080fd5b50610931600480360381019061092c9190613090565b6119be565b60405161093e9190612f8d565b60405180910390f35b34801561095357600080fd5b5061096e6004803603810190610969919061360f565b6119e1565b60405161097b9190612f8d565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a69190613355565b611a75565b005b3480156109b957600080fd5b506109c2611af8565b6040516109cf9190613194565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b0b57507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610b219061367e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4d9061367e565b8015610b9a5780601f10610b6f57610100808354040283529160200191610b9a565b820191906000526020600020905b815481529060010190602001808311610b7d57829003601f168201915b5050505050905090565b6000610baf82611afe565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bf5826113de565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5c90613721565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c84611b49565b73ffffffffffffffffffffffffffffffffffffffff161480610cb35750610cb281610cad611b49565b6119e1565b5b610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce9906137b3565b60405180910390fd5b610cfc8383611b51565b505050565b6000600980549050905090565b600081604051602001610d21919061384b565b604051602081830303815290604052805190602001209050919050565b610d46611c0a565b806010819055507fc9f68d4642b75238a09de01fc991dbaecb731624b8246a79f6bddfb265ab9c6581604051610d7c9190613194565b60405180910390a150565b610d98610d92611b49565b82611c88565b610dd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dce906138e3565b60405180910390fd5b610de2838383611d1d565b505050565b60115481565b610df5611c0a565b806011819055507fce84f3dad126a2cb9d67cdca12c64dc079f7a9a1a0728c5c4e16e4b5b2e4bc4d81604051610e2b9190613194565b60405180910390a150565b6000610e41836114d8565b8210610e82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7990613975565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6000610f0e8787604051602001610ef39291906139b6565b60405160208183030381529060405280519060200120610d0e565b9050848114610f52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4990613a7a565b60405180910390fd5b600060018686868660405160008152602001604052604051610f779493929190613aa9565b6020604051602081039080840390855afa158015610f99573d6000803e3d6000fd5b505050602060405103519050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102c90613b86565b60405180910390fd5b6013600087815260200190815260200160002060009054906101000a900460ff1615611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108d90613c18565b60405180910390fd5b5050505050505050565b6110a8611c0a565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b60136020528060005260406000206000915054906101000a900460ff1681565b611157611c0a565b6002600b540361119c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119390613c84565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff16826040516111cf90613cd5565b60006040518083038185875af1925050503d806000811461120c576040519150601f19603f3d011682016040523d82523d6000602084013e611211565b606091505b505090508061121f57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a232518260405161124e9190613194565b60405180910390a150506001600b81905550565b60004282116112a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129d90613d5c565b60405180910390fd5b60006103e842846112b79190613dab565b6112c19190613ddf565b90506000600d54826112d39190613ddf565b856112de9190613e50565b9050809250505092915050565b611306838383604051806020016040528060008152506117f6565b505050565b61131c611316611b49565b82611c88565b61135b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611352906138e3565b60405180910390fd5b61136481611f83565b50565b600f5481565b6000611377610d01565b82106113b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113af90613ef3565b60405180910390fd5b600982815481106113cc576113cb613f13565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611486576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147d90613f8e565b60405180910390fd5b80915050919050565b611497611c0a565b80600f819055507f48e50e8ecbfe9fa83d92fd45f81b044a22e6a14ab3bfbef5c58ae2f80b796fca816040516114cd9190613194565b60405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153f90614020565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611597611c0a565b6115a160006120a0565b565b600d5481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546115e29061367e565b80601f016020809104026020016040519081016040528092919081815260200182805461160e9061367e565b801561165b5780601f106116305761010080835404028352916020019161165b565b820191906000526020600020905b81548152906001019060200180831161163e57829003601f168201915b5050505050905090565b600e5481565b600e600081548092919061167e90614040565b91905055506000600e549050611698878787878787610edb565b60016013600087815260200190815260200160002060006101000a81548160ff0219169083151502179055506116cf818789612166565b50505050505050565b6116e0611c0a565b80600d819055507f6812e5d5d18adf9e51779dd1b67eef3cc61fdd5ca0289fcf7daefb629fb24974816040516117169190613194565b60405180910390a150565b600e600081548092919061173490614040565b91905055506000600e549050600061174c3484611262565b9050600061175a8285611935565b905060003411801561176c5750803410155b6117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a290614146565b60405180910390fd5b6117b6838386612166565b50505050565b6117ce6117c7611b49565b83836121b4565b5050565b60126020528060005260406000206000915090508060000154908060010154905082565b611807611801611b49565b83611c88565b611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d906138e3565b60405180910390fd5b61185284848484612320565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060006040518061048001604052806104568152602001614a6361045691399050600061190a826118c5601260008881526020019081526020016000206001015461237c565b6118e4601260008981526020019081526020016000206000015461237c565b6040516020016118f693929190614433565b6040516020818303038152906040526124dc565b90508060405160200161191d91906144dc565b60405160208183030381529060405292505050919050565b6000428211611979576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197090613d5c565b60405180910390fd5b60006103e8428461198a9190613dab565b6119949190613ddf565b90506000600d5482866119a79190613ddf565b6119b19190613ddf565b9050809250505092915050565b600042601260008481526020019081526020016000206001015411159050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611a7d611c0a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae390614570565b60405180910390fd5b611af5816120a0565b50565b60105481565b611b078161263f565b611b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3d90613f8e565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611bc4836113de565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611c12611b49565b73ffffffffffffffffffffffffffffffffffffffff16611c306115a9565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d906145dc565b60405180910390fd5b565b600080611c94836113de565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611cd65750611cd581856119e1565b5b80611d1457508373ffffffffffffffffffffffffffffffffffffffff16611cfc84610ba4565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611d3d826113de565b73ffffffffffffffffffffffffffffffffffffffff1614611d93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8a9061466e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df990614700565b60405180910390fd5b611e0d8383836126ab565b611e18600082611b51565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e689190613dab565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ebf9190614720565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f7e8383836126bb565b505050565b6000611f8e826113de565b9050611f9c816000846126ab565b611fa7600083611b51565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ff79190613dab565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461209c816000846126bb565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61217033846126c0565b604051806040016040528083815260200182815250601260008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612222576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612219906147a0565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123139190612f8d565b60405180910390a3505050565b61232b848484611d1d565b612337848484846126de565b612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236d90614832565b60405180910390fd5b50505050565b6060600082036123c3576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506124d7565b600082905060005b600082146123f55780806123de90614040565b915050600a826123ee9190613e50565b91506123cb565b60008167ffffffffffffffff81111561241157612410613461565b5b6040519080825280601f01601f1916602001820160405280156124435781602001600182028036833780820191505090505b5090505b600085146124d05760018261245c9190613dab565b9150600a8561246b9190614852565b60306124779190614720565b60f81b81838151811061248d5761248c613f13565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856124c99190613e50565b9450612447565b8093505050505b919050565b606060008251036124fe5760405180602001604052806000815250905061263a565b6000604051806060016040528060408152602001614eb9604091399050600060036002855161252d9190614720565b6125379190613e50565b60046125439190613ddf565b67ffffffffffffffff81111561255c5761255b613461565b5b6040519080825280601f01601f19166020018201604052801561258e5781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156125fa576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184536001840193505061259f565b5050600386510660018114612616576002811461262957612631565b603d6001830353603d6002830353612631565b603d60018303535b50505080925050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6126b6838383612865565b505050565b505050565b6126da828260405180602001604052806000815250612977565b5050565b60006126ff8473ffffffffffffffffffffffffffffffffffffffff166129d2565b15612858578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612728611b49565b8786866040518563ffffffff1660e01b815260040161274a94939291906148cd565b6020604051808303816000875af192505050801561278657506040513d601f19601f82011682018060405250810190612783919061492e565b60015b612808573d80600081146127b6576040519150601f19603f3d011682016040523d82523d6000602084013e6127bb565b606091505b506000815103612800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f790614832565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061285d565b600190505b949350505050565b6128708383836129f5565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036128b2576128ad816129fa565b6128f1565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146128f0576128ef8382612a43565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129335761292e81612bb0565b612972565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612971576129708282612c81565b5b5b505050565b6129818383612d00565b61298e60008484846126de565b6129cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c490614832565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612a50846114d8565b612a5a9190613dab565b9050600060086000848152602001908152602001600020549050818114612b3f576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050612bc49190613dab565b90506000600a6000848152602001908152602001600020549050600060098381548110612bf457612bf3613f13565b5b906000526020600020015490508060098381548110612c1657612c15613f13565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a6000858152602001908152602001600020600090556009805480612c6557612c6461495b565b5b6001900381819060005260206000200160009055905550505050565b6000612c8c836114d8565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612d6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d66906149d6565b60405180910390fd5b612d788161263f565b15612db8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612daf90614a42565b60405180910390fd5b612dc4600083836126ab565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e149190614720565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ed5600083836126bb565b5050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f2281612eed565b8114612f2d57600080fd5b50565b600081359050612f3f81612f19565b92915050565b600060208284031215612f5b57612f5a612ee3565b5b6000612f6984828501612f30565b91505092915050565b60008115159050919050565b612f8781612f72565b82525050565b6000602082019050612fa26000830184612f7e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612fe2578082015181840152602081019050612fc7565b60008484015250505050565b6000601f19601f8301169050919050565b600061300a82612fa8565b6130148185612fb3565b9350613024818560208601612fc4565b61302d81612fee565b840191505092915050565b600060208201905081810360008301526130528184612fff565b905092915050565b6000819050919050565b61306d8161305a565b811461307857600080fd5b50565b60008135905061308a81613064565b92915050565b6000602082840312156130a6576130a5612ee3565b5b60006130b48482850161307b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130e8826130bd565b9050919050565b6130f8816130dd565b82525050565b600060208201905061311360008301846130ef565b92915050565b613122816130dd565b811461312d57600080fd5b50565b60008135905061313f81613119565b92915050565b6000806040838503121561315c5761315b612ee3565b5b600061316a85828601613130565b925050602061317b8582860161307b565b9150509250929050565b61318e8161305a565b82525050565b60006020820190506131a96000830184613185565b92915050565b6000819050919050565b6131c2816131af565b81146131cd57600080fd5b50565b6000813590506131df816131b9565b92915050565b6000602082840312156131fb576131fa612ee3565b5b6000613209848285016131d0565b91505092915050565b61321b816131af565b82525050565b60006020820190506132366000830184613212565b92915050565b60008060006060848603121561325557613254612ee3565b5b600061326386828701613130565b935050602061327486828701613130565b92505060406132858682870161307b565b9150509250925092565b600060ff82169050919050565b6132a58161328f565b81146132b057600080fd5b50565b6000813590506132c28161329c565b92915050565b60008060008060008060c087890312156132e5576132e4612ee3565b5b60006132f389828a0161307b565b965050602061330489828a0161307b565b955050604061331589828a016131d0565b945050606061332689828a016132b3565b935050608061333789828a016131d0565b92505060a061334889828a016131d0565b9150509295509295509295565b60006020828403121561336b5761336a612ee3565b5b600061337984828501613130565b91505092915050565b6000806040838503121561339957613398612ee3565b5b60006133a78582860161307b565b92505060206133b88582860161307b565b9150509250929050565b6133cb81612f72565b81146133d657600080fd5b50565b6000813590506133e8816133c2565b92915050565b6000806040838503121561340557613404612ee3565b5b600061341385828601613130565b9250506020613424858286016133d9565b9150509250929050565b60006040820190506134436000830185613185565b6134506020830184613185565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61349982612fee565b810181811067ffffffffffffffff821117156134b8576134b7613461565b5b80604052505050565b60006134cb612ed9565b90506134d78282613490565b919050565b600067ffffffffffffffff8211156134f7576134f6613461565b5b61350082612fee565b9050602081019050919050565b82818337600083830152505050565b600061352f61352a846134dc565b6134c1565b90508281526020810184848401111561354b5761354a61345c565b5b61355684828561350d565b509392505050565b600082601f83011261357357613572613457565b5b813561358384826020860161351c565b91505092915050565b600080600080608085870312156135a6576135a5612ee3565b5b60006135b487828801613130565b94505060206135c587828801613130565b93505060406135d68782880161307b565b925050606085013567ffffffffffffffff8111156135f7576135f6612ee8565b5b6136038782880161355e565b91505092959194509250565b6000806040838503121561362657613625612ee3565b5b600061363485828601613130565b925050602061364585828601613130565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061369657607f821691505b6020821081036136a9576136a861364f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061370b602183612fb3565b9150613716826136af565b604082019050919050565b6000602082019050818103600083015261373a816136fe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b600061379d603e83612fb3565b91506137a882613741565b604082019050919050565b600060208201905081810360008301526137cc81613790565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613814601c836137d3565b915061381f826137de565b601c82019050919050565b6000819050919050565b613845613840826131af565b61382a565b82525050565b600061385682613807565b91506138628284613834565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006138cd602e83612fb3565b91506138d882613871565b604082019050919050565b600060208201905081810360008301526138fc816138c0565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b600061395f602b83612fb3565b915061396a82613903565b604082019050919050565b6000602082019050818103600083015261398e81613952565b9050919050565b6000819050919050565b6139b06139ab8261305a565b613995565b82525050565b60006139c2828561399f565b6020820191506139d2828461399f565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20657870697265734174202b2072657175657374735065724d696c6c6973656360208201527f6f6e642e20204578706c61696e20796f757273656c6621000000000000000000604082015250565b6000613a64605783612fb3565b9150613a6f826139e2565b606082019050919050565b60006020820190508181036000830152613a9381613a57565b9050919050565b613aa38161328f565b82525050565b6000608082019050613abe6000830187613212565b613acb6020830186613a9a565b613ad86040830185613212565b613ae56060830184613212565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000613b70604183612fb3565b9150613b7b82613aee565b606082019050919050565b60006020820190508181036000830152613b9f81613b63565b9050919050565b7f5468697320667265654d696e742068617320616c7265616479206265656e207260008201527f656465656d65642e2020486f7720656d626172617373696e672e000000000000602082015250565b6000613c02603a83612fb3565b9150613c0d82613ba6565b604082019050919050565b60006020820190508181036000830152613c3181613bf5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613c6e601f83612fb3565b9150613c7982613c38565b602082019050919050565b60006020820190508181036000830152613c9d81613c61565b9050919050565b600081905092915050565b50565b6000613cbf600083613ca4565b9150613cca82613caf565b600082019050919050565b6000613ce082613cb2565b9150819050919050565b7f54686520657870697265734174206d75737420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b6000613d46602383612fb3565b9150613d5182613cea565b604082019050919050565b60006020820190508181036000830152613d7581613d39565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613db68261305a565b9150613dc18361305a565b9250828203905081811115613dd957613dd8613d7c565b5b92915050565b6000613dea8261305a565b9150613df58361305a565b9250828202613e038161305a565b91508282048414831517613e1a57613e19613d7c565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e5b8261305a565b9150613e668361305a565b925082613e7657613e75613e21565b5b828204905092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613edd602c83612fb3565b9150613ee882613e81565b604082019050919050565b60006020820190508181036000830152613f0c81613ed0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613f78601883612fb3565b9150613f8382613f42565b602082019050919050565b60006020820190508181036000830152613fa781613f6b565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061400a602983612fb3565b915061401582613fae565b604082019050919050565b6000602082019050818103600083015261403981613ffd565b9050919050565b600061404b8261305a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361407d5761407c613d7c565b5b600182019050919050565b7f596f75206d7573742073656e642074686520636f7374206f662074686973207260008201527f617465206c696d697420696e6372656173652e2020546f20636865636b20746860208201527f6520636f73742c20757365207468652063616c63756c617465436f737420667560408201527f6e6374696f6e2e00000000000000000000000000000000000000000000000000606082015250565b6000614130606783612fb3565b915061413b82614088565b608082019050919050565b6000602082019050818103600083015261415f81614123565b9050919050565b7f7b226e616d65223a20224c69742050726f746f636f6c2052617465204c696d6960008201527f7420496e637265617365222c20226465736372697074696f6e223a202254686960208201527f73204e465420656e7469746c65732074686520686f6c64657220746f2061207260408201527f617465206c696d697420696e637265617365206f6e20746865204c697420507260608201527f6f746f636f6c204e6574776f726b222c2022696d6167655f64617461223a2022608082015250565b600061423460a0836137d3565b915061423f82614166565b60a082019050919050565b600081519050919050565b60006142608261424a565b61426a8185613ca4565b935061427a818560208601612fc4565b80840191505092915050565b7f222c2261747472696275746573223a205b7b22646973706c61795f747970652260008201527f3a202264617465222c202274726169745f74797065223a20224578706972617460208201527f696f6e2044617465222c202276616c7565223a20000000000000000000000000604082015250565b60006143086054836137d3565b915061431382614286565b605482019050919050565b600061432982612fa8565b61433381856137d3565b9350614343818560208601612fc4565b80840191505092915050565b7f7d2c207b22646973706c61795f74797065223a20226e756d626572222c20227460008201527f726169745f74797065223a2022526571756573747320506572204d696c6c697360208201527f65636f6e64222c202276616c7565223a20000000000000000000000000000000604082015250565b60006143d16051836137d3565b91506143dc8261434f565b605182019050919050565b7f7d5d7d0000000000000000000000000000000000000000000000000000000000600082015250565b600061441d6003836137d3565b9150614428826143e7565b600382019050919050565b600061443e82614227565b915061444a8286614255565b9150614455826142fb565b9150614461828561431e565b915061446c826143c4565b9150614478828461431e565b915061448382614410565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006144c6601d836137d3565b91506144d182614490565b601d82019050919050565b60006144e7826144b9565b91506144f3828461431e565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061455a602683612fb3565b9150614565826144fe565b604082019050919050565b600060208201905081810360008301526145898161454d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145c6602083612fb3565b91506145d182614590565b602082019050919050565b600060208201905081810360008301526145f5816145b9565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614658602583612fb3565b9150614663826145fc565b604082019050919050565b600060208201905081810360008301526146878161464b565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006146ea602483612fb3565b91506146f58261468e565b604082019050919050565b60006020820190508181036000830152614719816146dd565b9050919050565b600061472b8261305a565b91506147368361305a565b925082820190508082111561474e5761474d613d7c565b5b92915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061478a601983612fb3565b915061479582614754565b602082019050919050565b600060208201905081810360008301526147b98161477d565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061481c603283612fb3565b9150614827826147c0565b604082019050919050565b6000602082019050818103600083015261484b8161480f565b9050919050565b600061485d8261305a565b91506148688361305a565b92508261487857614877613e21565b5b828206905092915050565b600082825260208201905092915050565b600061489f8261424a565b6148a98185614883565b93506148b9818560208601612fc4565b6148c281612fee565b840191505092915050565b60006080820190506148e260008301876130ef565b6148ef60208301866130ef565b6148fc6040830185613185565b818103606083015261490e8184614894565b905095945050505050565b60008151905061492881612f19565b92915050565b60006020828403121561494457614943612ee3565b5b600061495284828501614919565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006149c0602083612fb3565b91506149cb8261498a565b602082019050919050565b600060208201905081810360008301526149ef816149b3565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614a2c601c83612fb3565b9150614a37826149f6565b602082019050919050565b60006020820190508181036000830152614a5b81614a1f565b905091905056fe3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d273130383027206865696768743d2731303830272066696c6c3d276e6f6e652720786d6c6e733a763d2768747470733a2f2f76656374612e696f2f6e616e6f273e3c7061746820643d274d3336332e303736203339322e323237732d2e3937372031382e3532342d33362e3837342037382e393437632d34312e3537362037302e3031382d34352e343831203135312e3937382d332e303137203232302e342038392e353231203134342e323435203333322e343831203134312e3532203432322e3535362e3038392033342e3833322d35342e3730372034342e3831362d3131372e3437392033322e3932342d3138312e323438203020302d32382e3831392d3133332e3134342d3132372e3233372d3231372e30393920312e35353320312e33303820352e3336392031392e31323220362e3130312032362e37323220322e3234312032332e3335342e3034352034372e3833382d372e3738372037302e3036322d352e3734362031362e33332d31332e3731312033302e3436372d32372e3137382034312e33363820302d332e3831312d2e3935342d31302e3633352d2e3937362d31322e3931382d2e3634342d34362e3530382d31382e3635392d38392e3538322d34382e3031312d3132352e3734332d32352e3634372d33312e3535322d36302e3831322d35332e3038392d39372e38342d36382e3933322e39333120332e31393120322e3636322031362e34313920322e3930362031392e30333320312e3930382032312e39353820322e3236332035322e3731332d2e3632312037342e363439732d372e3833322033332e3837382d31342e3535342035342e343431632d31302e3138342033312e3137352d32342e30352035342e3238352d34312e3632312038322e3030342d332e323420352e3039362d31322e3931332031392e3037382d31382e3038322032362e313436203020302d382e3839372d35362e3139312d34302e3636372d38372e393231682d2e3032327a272066696c6c3d2723303030272f3e3c7061746820643d274d3536322e352032372e32386c3431302e323739203233362e3837346331332e39323320382e3033392032322e352032322e3839352032322e352033382e393731763437332e373563302031362e3037362d382e3537372033302e3933322d32322e352033382e3937314c3536322e3520313035322e3732632d31332e39323320382e30342d33312e30373720382e30342d343520304c3130372e323231203831352e383436632d31332e3932332d382e3033392d32322e352d32322e3839352d32322e352d33382e393731762d3437332e37356134352034352030203020312032322e352d33382e3937314c3531372e352032372e323861343520343520302030203120343520307a27207374726f6b653d272330303027207374726f6b652d77696474683d2732342e3735272f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ad3a2a5fc856b8ef8ede76806528a646a1e3761d7694275fbb7f9c182ca3f5c864736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdditionalRequestsPerMillisecondCost","type":"uint256"}],"name":"AdditionalRequestsPerSecondCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"FreeRequestsPerRateLimitWindowSet","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":false,"internalType":"uint256","name":"newRLIHolderRateLimitWindowMilliseconds","type":"uint256"}],"name":"RLIHolderRateLimitWindowMillisecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRateLimitWindowMilliseconds","type":"uint256"}],"name":"RateLimitWindowMillisecondsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"RLIHolderRateLimitWindowMilliseconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"additionalRequestsPerMillisecondCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestsPerMillisecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payingAmount","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"calculateRequestsPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"capacity","outputs":[{"internalType":"uint256","name":"requestsPerMillisecond","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRateLimitWindowMilliseconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerMillisecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"},{"internalType":"uint256","name":"requestsPerMillisecond","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeRequestsPerRateLimitWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"isExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"redeemedFreeMints","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAdditionalRequestsPerMillisecondCost","type":"uint256"}],"name":"setAdditionalRequestsPerSecondCost","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFreeRequestsPerRateLimitWindow","type":"uint256"}],"name":"setFreeRequestsPerRateLimitWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRLIHolderRateLimitWindowMilliseconds","type":"uint256"}],"name":"setRLIHolderRateLimitWindowMilliseconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRateLimitWindowMilliseconds","type":"uint256"}],"name":"setRateLimitWindowMilliseconds","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/SoloNetPKP.json b/deployments/rolluptestnet_987/SoloNetPKP.json deleted file mode 100644 index 29906e8..0000000 --- a/deployments/rolluptestnet_987/SoloNetPKP.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0xd653f1B6BcDd341103C259b766c58E1d5340556e","bytecode":"0x60806040523480156200001157600080fd5b506040518060400160405280601481526020017f50726f6772616d6d61626c65204b6579706169720000000000000000000000008152506040518060400160405280600381526020017f504b50000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000559565b508060019081620000a1919062000559565b505050620000c4620000b86200013c60201b60201c565b6200014460201b60201c565b6001600b81905550655af3107a4000600e8190555033600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001353360116200020a60201b6200240d1790919060201c565b5062000640565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006200023a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200024260201b60201c565b905092915050565b6000620002568383620002bc60201b60201c565b620002b1578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050620002b6565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200036157607f821691505b60208210810362000377576200037662000319565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003a2565b620003ed8683620003a2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200043a620004346200042e8462000405565b6200040f565b62000405565b9050919050565b6000819050919050565b620004568362000419565b6200046e620004658262000441565b848454620003af565b825550505050565b600090565b6200048562000476565b620004928184846200044b565b505050565b5b81811015620004ba57620004ae6000826200047b565b60018101905062000498565b5050565b601f8211156200050957620004d3816200037d565b620004de8462000392565b81016020851015620004ee578190505b62000506620004fd8562000392565b83018262000497565b50505b505050565b600082821c905092915050565b60006200052e600019846008026200050e565b1980831691505092915050565b60006200054983836200051b565b9150826002028217905092915050565b6200056482620002df565b67ffffffffffffffff81111562000580576200057f620002ea565b5b6200058c825462000348565b62000599828285620004be565b600060209050601f831160018114620005d15760008415620005bc578287015190505b620005c885826200053b565b86555062000638565b601f198416620005e1866200037d565b60005b828110156200060b57848901518255600182019150602085019450602081019050620005e4565b868310156200062b578489015162000627601f8916826200051b565b8355505b6001600288020188555050505b505050505050565b61598b80620006506000396000f3fe60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122050079be92fc9d5ddf7cbe0f0a8d11a189508222c82430d3903f337e939c0ee0164736f6c63430008110033","deployedBytecode":"0x60806040526004361061027d5760003560e01c8063715018a61161014f578063a22cb465116100c1578063cc293a2d1161007a578063cc293a2d14610a0b578063de18a50814610a3b578063e985e9c514610a78578063ef6fd87814610ab5578063f2fde38b14610af2578063f4e0d9ac14610b1b5761027d565b8063a22cb465146108e9578063b88d4fde14610912578063b94a21021461093b578063bd4986a014610966578063bdb4b848146109a3578063c87b56dd146109ce5761027d565b80638545f4ea116101135780638545f4ea146107d75780638da5cb5b146108005780639004525f1461082b5780639388f12e1461086857806395d89b411461089357806397016f3f146108be5761027d565b8063715018a6146106ed57806371c9ce13146107045780637ba0e2e7146107415780637bd3e3f614610771578063831324ea146107ae5761027d565b806342842e0e116101f357806356e3a1ae116101ac57806356e3a1ae146105a75780635f49663c146105e45780636352211e1461060d57806364c7605e1461064a5780636f2096371461068757806370a08231146106b05761027d565b806342842e0e1461048757806342966c68146104b05780634c19eae6146104d95780634cf088d9146105025780634f558e791461052d5780634f6ccce71461056a5761027d565b80631ea89a22116102455780631ea89a221461037b5780631f275713146103a457806323b872dd146103e15780632f745c591461040a5780633b189852146104475780633ccfd60b146104705761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613a96565b610b44565b6040516102b69190613ade565b60405180910390f35b3480156102cb57600080fd5b506102d4610c7e565b6040516102e19190613b89565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613be1565b610d10565b60405161031e9190613c4f565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613c96565b610d56565b005b34801561035c57600080fd5b50610365610e6d565b6040516103729190613ce5565b60405180910390f35b34801561038757600080fd5b506103a2600480360381019061039d9190613d00565b610e7a565b005b3480156103b057600080fd5b506103cb60048036038101906103c69190613d63565b610f09565b6040516103d89190613d9f565b60405180910390f35b3480156103ed57600080fd5b5061040860048036038101906104039190613dba565b610f39565b005b34801561041657600080fd5b50610431600480360381019061042c9190613c96565b610f99565b60405161043e9190613ce5565b60405180910390f35b34801561045357600080fd5b5061046e60048036038101906104699190613d00565b61103e565b005b34801561047c57600080fd5b506104856110cd565b005b34801561049357600080fd5b506104ae60048036038101906104a99190613dba565b6111e0565b005b3480156104bc57600080fd5b506104d760048036038101906104d29190613be1565b611200565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190613e46565b61125c565b005b34801561050e57600080fd5b50610517611426565b6040516105249190613f20565b60405180910390f35b34801561053957600080fd5b50610554600480360381019061054f9190613be1565b61144c565b6040516105619190613ade565b60405180910390f35b34801561057657600080fd5b50610591600480360381019061058c9190613be1565b61145e565b60405161059e9190613ce5565b60405180910390f35b3480156105b357600080fd5b506105ce60048036038101906105c99190613be1565b6114cf565b6040516105db9190613ade565b60405180910390f35b3480156105f057600080fd5b5061060b60048036038101906106069190613d00565b6114ef565b005b34801561061957600080fd5b50610634600480360381019061062f9190613be1565b61157e565b6040516106419190613c4f565b60405180910390f35b34801561065657600080fd5b50610671600480360381019061066c9190614070565b61162f565b60405161067e9190613ce5565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a99190613d00565b6117bd565b005b3480156106bc57600080fd5b506106d760048036038101906106d29190613d00565b611820565b6040516106e49190613ce5565b60405180910390f35b3480156106f957600080fd5b506107026118d7565b005b34801561071057600080fd5b5061072b6004803603810190610726919061414a565b6118eb565b6040516107389190613ce5565b60405180910390f35b61075b6004803603810190610756919061414a565b611966565b6040516107689190613ce5565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613be1565b611a20565b6040516107a591906141e8565b60405180910390f35b3480156107ba57600080fd5b506107d560048036038101906107d09190613d00565b611ac0565b005b3480156107e357600080fd5b506107fe60048036038101906107f99190613be1565b611b23565b005b34801561080c57600080fd5b50610815611b6c565b6040516108229190613c4f565b60405180910390f35b34801561083757600080fd5b50610852600480360381019061084d919061420a565b611b96565b60405161085f9190613ce5565b60405180910390f35b34801561087457600080fd5b5061087d611c40565b60405161088a91906142d4565b60405180910390f35b34801561089f57600080fd5b506108a8611c66565b6040516108b59190613b89565b60405180910390f35b3480156108ca57600080fd5b506108d3611cf8565b6040516108e09190614310565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b9190614357565b611d1e565b005b34801561091e57600080fd5b5061093960048036038101906109349190614397565b611d34565b005b34801561094757600080fd5b50610950611d96565b60405161095d9190613c4f565b60405180910390f35b34801561097257600080fd5b5061098d60048036038101906109889190613be1565b611dbc565b60405161099a9190613c4f565b60405180910390f35b3480156109af57600080fd5b506109b8611e8c565b6040516109c59190613ce5565b60405180910390f35b3480156109da57600080fd5b506109f560048036038101906109f09190613be1565b611e92565b604051610a029190613b89565b60405180910390f35b610a256004803603810190610a20919061441a565b612016565b604051610a329190613ce5565b60405180910390f35b348015610a4757600080fd5b50610a626004803603810190610a5d9190613d00565b6121aa565b604051610a6f9190613ce5565b60405180910390f35b348015610a8457600080fd5b50610a9f6004803603810190610a9a9190614492565b6121c2565b604051610aac9190613ade565b60405180910390f35b348015610ac157600080fd5b50610adc6004803603810190610ad79190613be1565b612256565b604051610ae991906141e8565b60405180910390f35b348015610afe57600080fd5b50610b196004803603810190610b149190613d00565b6122fb565b005b348015610b2757600080fd5b50610b426004803603810190610b3d9190613d00565b61237e565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c0f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c7757507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060008054610c8d90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb990614501565b8015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b6000610d1b8261243d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610d618261157e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610dd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc8906145a4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610df0612488565b73ffffffffffffffffffffffffffffffffffffffff161480610e1f5750610e1e81610e19612488565b6121c2565b5b610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590614636565b60405180910390fd5b610e688383612490565b505050565b6000600980549050905090565b610e82612549565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f42d2ac2cd8a457cf976d513bacdc167baa2ff2cd2706c98d222bb035b89d496960405160405180910390a250565b600081604051602001610f1c91906146ce565b604051602081830303815290604052805190602001209050919050565b610f4a610f44612488565b826125c7565b610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8090614766565b60405180910390fd5b610f9483838361265c565b505050565b6000610fa483611820565b8210610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc906147f8565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611046612549565b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65d3e06a561c77a07da59b8b2ca10214ae08fe21cc2953a90db0ac8b5b7c437160405160405180910390a250565b6110d5612549565b6002600b540361111a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111190614864565b60405180910390fd5b6002600b81905550600047905060003373ffffffffffffffffffffffffffffffffffffffff168260405161114d906148b5565b60006040518083038185875af1925050503d806000811461118a576040519150601f19603f3d011682016040523d82523d6000602084013e61118f565b606091505b505090508061119d57600080fd5b7fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a23251826040516111cc9190613ce5565b60405180910390a150506001600b81905550565b6111fb83838360405180602001604052806000815250611d34565b505050565b61121161120b612488565b826125c7565b611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614766565b60405180910390fd5b611259816128c2565b50565b600061128f3087604051602001611274929190614933565b60405160208183030381529060405280519060200120610f09565b90508481146112d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ca906149d1565b60405180910390fd5b6000600186868686604051600081526020016040526040516112f89493929190614a00565b6020604051602081039080840390855afa15801561131a573d6000803e3d6000fd5b505050602060405103519050600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad90614add565b60405180910390fd5b600015156015600089815260200190815260200160002060009054906101000a900460ff1615151461141d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141490614b6f565b60405180910390fd5b50505050505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611457826129df565b9050919050565b6000611468610e6d565b82106114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614c01565b60405180910390fd5b600982815481106114bd576114bc614c21565b5b90600052602060002001549050919050565b60156020528060005260406000206000915054906101000a900460ff1681565b6114f7612549565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f446c3422d569626abc16e1497dfa8270f1192bd56ea9ec8890b09705ddc275ad60405160405180910390a250565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90614c9c565b60405180910390fd5b80915050919050565b6000611645326011612a4b90919063ffffffff16565b611684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167b90614d08565b60405180910390fd5b611691878686868661125c565b600061169d8930612a7b565b90506001601560008a815260200190815260200160002060006101000a81548160ff021916908315150217905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788289600067ffffffffffffffff81111561172657611725613f45565b5b6040519080825280602002602001820160405280156117545781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161177393929190614de6565b600060405180830381600087803b15801561178d57600080fd5b505af11580156117a1573d6000803e3d6000fd5b505050506117ae816128c2565b80915050979650505050505050565b6117c5612549565b6117d9816011612bb790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe8160405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188790614e9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118df612549565b6118e96000612be7565b565b600080828051906020012060001c9050600060136000838152602001908152602001600020805461191b90614501565b90501461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490614f09565b60405180910390fd5b80915050919050565b6000600e5434146119ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a390614f75565b60405180910390fd5b6119c0326011612a4b90919063ffffffff16565b6119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690614d08565b60405180910390fd5b6000611a0a836118eb565b9050611a168333612a7b565b5080915050919050565b60136020528060005260406000206000915090508054611a3f90614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6b90614501565b8015611ab85780601f10611a8d57610100808354040283529160200191611ab8565b820191906000526020600020905b815481529060010190602001808311611a9b57829003601f168201915b505050505081565b611ac8612549565b611adc81601161240d90919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167fcddac40078270fda4a2cd64a6089b372413df61e8de795e484d9c054c44ce16f60405160405180910390a250565b611b2b612549565b80600e819055507f653b8b44976b2e5c016e082d134653d04dea9dbef92055038cca38c93007035581604051611b619190613ce5565b60405180910390a150565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611bac326011612a4b90919063ffffffff16565b611beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be290614d08565b60405180910390fd5b611bf8868686868661125c565b6000611c048833612a7b565b905060016015600089815260200190815260200160002060006101000a81548160ff021916908315150217905550809150509695505050505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060018054611c7590614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614501565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d30611d29612488565b8383612cad565b5050565b611d45611d3f612488565b836125c7565b611d84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7b90614766565b60405180910390fd5b611d9084848484612e19565b50505050565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e7160016040601360008781526020019081526020016000208054611de490614501565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1090614501565b8015611e5d5780601f10611e3257610100808354040283529160200191611e5d565b820191906000526020600020905b815481529060010190602001808311611e4057829003601f168201915b5050505050612e759092919063ffffffff16565b90506000818051906020012090508060001c92505050919050565b600e5481565b6060611ed26040518060400160405280601181526020017f67657474696e6720746f6b656e20757269000000000000000000000000000000815250612f93565b6000611edd83612256565b9050611f1d6040518060400160405280601f81526020017f676f74207075626b65792c2067657474696e6720657468206164647265737300815250612f93565b6000611f2884611dbc565b9050611f686040518060400160405280601081526020017f63616c6c696e6720746f6b656e55524900000000000000000000000000000000815250612f93565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663950462ee8584846040518463ffffffff1660e01b8152600401611fc793929190614f95565b600060405180830381865afa158015611fe4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061200d9190615074565b92505050919050565b6000600e54341461205c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205390614f75565b60405180910390fd5b612070326011612a4b90919063ffffffff16565b6120af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a690614d08565b60405180910390fd5b60006120bb8430612a7b565b9050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a4315788285600067ffffffffffffffff81111561211857612117613f45565b5b6040519080825280602002602001820160405280156121465781602001602082028036833780820191505090505b506040518463ffffffff1660e01b815260040161216593929190614de6565b600060405180830381600087803b15801561217f57600080fd5b505af1158015612193573d6000803e3d6000fd5b505050506121a0816128c2565b8091505092915050565b60146020528060005260406000206000915090505481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060136000838152602001908152602001600020805461227690614501565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614501565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b50505050509050919050565b612303612549565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612372576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123699061512f565b60405180910390fd5b61237b81612be7565b50565b612386612549565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f524b317898d91e941d8311edbdd1bf568e07309f08e11f7ef94c053a9e35f91860405160405180910390a250565b6000612435836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61302c565b905092915050565b612446816129df565b612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614c9c565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166125038361157e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612551612488565b73ffffffffffffffffffffffffffffffffffffffff1661256f611b6c565b73ffffffffffffffffffffffffffffffffffffffff16146125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc9061519b565b60405180910390fd5b565b6000806125d38361157e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612615575061261481856121c2565b5b8061265357508373ffffffffffffffffffffffffffffffffffffffff1661263b84610d10565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661267c8261157e565b73ffffffffffffffffffffffffffffffffffffffff16146126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c99061522d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612738906152bf565b60405180910390fd5b61274c83838361309c565b612757600082612490565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127a7919061530e565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546127fe9190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128bd8383836130ac565b505050565b60006128cd8261157e565b90506128db8160008461309c565b6128e6600083612490565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612936919061530e565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46129db816000846130ac565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b1565b905092915050565b600080838051906020012060001c90506000601360008381526020019081526020016000208054612aab90614501565b905014612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae490614f09565b60405180910390fd5b83601360008381526020019081526020016000209081612b0d9190615518565b506000612b1982611dbc565b905081601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612ba157612b9c84836130d4565b612bac565b612bab84836132ad565b5b819250505092915050565b6000612bdf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6132cb565b905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1290615636565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612e0c9190613ade565b60405180910390a3505050565b612e2484848461265c565b612e30848484846133df565b612e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e66906156c8565b60405180910390fd5b50505050565b606081601f83612e859190615342565b1015612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615734565b60405180910390fd5b8183612ed29190615342565b84511015612f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0c906157a0565b60405180910390fd5b6060821560008114612f365760405191506000825260208201604052612f87565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612f745780518352602083019250602081019050612f57565b50868552601f19601f8301166040525050505b50809150509392505050565b61302981604051602401612fa79190613b89565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613566565b50565b600061303883836130b1565b613091578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613096565b600090505b92915050565b6130a783838361358f565b505050565b505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313a9061580c565b60405180910390fd5b61314c816129df565b1561318c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318390615878565b60405180910390fd5b6131986000838361309c565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131e89190615342565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a9600083836130ac565b5050565b6132c78282604051806020016040528060008152506136a1565b5050565b600080836001016000848152602001908152602001600020549050600081146133d35760006001826132fd919061530e565b9050600060018660000180549050613315919061530e565b905081811461338457600086600001828154811061333657613335614c21565b5b906000526020600020015490508087600001848154811061335a57613359614c21565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061339857613397615898565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506133d9565b60009150505b92915050565b60006134008473ffffffffffffffffffffffffffffffffffffffff166136fc565b15613559578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613429612488565b8786866040518563ffffffff1660e01b815260040161344b94939291906158c7565b6020604051808303816000875af192505050801561348757506040513d601f19601f820116820180604052508101906134849190615928565b60015b613509573d80600081146134b7576040519150601f19603f3d011682016040523d82523d6000602084013e6134bc565b606091505b506000815103613501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134f8906156c8565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061355e565b600190505b949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b61359a83838361371f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036135dc576135d781613724565b61361b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461361a57613619838261376d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361365d57613658816138da565b61369c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461369b5761369a82826139ab565b5b5b505050565b6136ab83836130d4565b6136b860008484846133df565b6136f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136ee906156c8565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161377a84611820565b613784919061530e565b9050600060086000848152602001908152602001600020549050818114613869576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016009805490506138ee919061530e565b90506000600a600084815260200190815260200160002054905060006009838154811061391e5761391d614c21565b5b9060005260206000200154905080600983815481106139405761393f614c21565b5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061398f5761398e615898565b5b6001900381819060005260206000200160009055905550505050565b60006139b683611820565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613a7381613a3e565b8114613a7e57600080fd5b50565b600081359050613a9081613a6a565b92915050565b600060208284031215613aac57613aab613a34565b5b6000613aba84828501613a81565b91505092915050565b60008115159050919050565b613ad881613ac3565b82525050565b6000602082019050613af36000830184613acf565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b33578082015181840152602081019050613b18565b60008484015250505050565b6000601f19601f8301169050919050565b6000613b5b82613af9565b613b658185613b04565b9350613b75818560208601613b15565b613b7e81613b3f565b840191505092915050565b60006020820190508181036000830152613ba38184613b50565b905092915050565b6000819050919050565b613bbe81613bab565b8114613bc957600080fd5b50565b600081359050613bdb81613bb5565b92915050565b600060208284031215613bf757613bf6613a34565b5b6000613c0584828501613bcc565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c3982613c0e565b9050919050565b613c4981613c2e565b82525050565b6000602082019050613c646000830184613c40565b92915050565b613c7381613c2e565b8114613c7e57600080fd5b50565b600081359050613c9081613c6a565b92915050565b60008060408385031215613cad57613cac613a34565b5b6000613cbb85828601613c81565b9250506020613ccc85828601613bcc565b9150509250929050565b613cdf81613bab565b82525050565b6000602082019050613cfa6000830184613cd6565b92915050565b600060208284031215613d1657613d15613a34565b5b6000613d2484828501613c81565b91505092915050565b6000819050919050565b613d4081613d2d565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b600060208284031215613d7957613d78613a34565b5b6000613d8784828501613d4e565b91505092915050565b613d9981613d2d565b82525050565b6000602082019050613db46000830184613d90565b92915050565b600080600060608486031215613dd357613dd2613a34565b5b6000613de186828701613c81565b9350506020613df286828701613c81565b9250506040613e0386828701613bcc565b9150509250925092565b600060ff82169050919050565b613e2381613e0d565b8114613e2e57600080fd5b50565b600081359050613e4081613e1a565b92915050565b600080600080600060a08688031215613e6257613e61613a34565b5b6000613e7088828901613bcc565b9550506020613e8188828901613d4e565b9450506040613e9288828901613e31565b9350506060613ea388828901613d4e565b9250506080613eb488828901613d4e565b9150509295509295909350565b6000819050919050565b6000613ee6613ee1613edc84613c0e565b613ec1565b613c0e565b9050919050565b6000613ef882613ecb565b9050919050565b6000613f0a82613eed565b9050919050565b613f1a81613eff565b82525050565b6000602082019050613f356000830184613f11565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f7d82613b3f565b810181811067ffffffffffffffff82111715613f9c57613f9b613f45565b5b80604052505050565b6000613faf613a2a565b9050613fbb8282613f74565b919050565b600067ffffffffffffffff821115613fdb57613fda613f45565b5b613fe482613b3f565b9050602081019050919050565b82818337600083830152505050565b600061401361400e84613fc0565b613fa5565b90508281526020810184848401111561402f5761402e613f40565b5b61403a848285613ff1565b509392505050565b600082601f83011261405757614056613f3b565b5b8135614067848260208601614000565b91505092915050565b600080600080600080600060e0888a03121561408f5761408e613a34565b5b600088013567ffffffffffffffff8111156140ad576140ac613a39565b5b6140b98a828b01614042565b97505060206140ca8a828b01613bcc565b965050604088013567ffffffffffffffff8111156140eb576140ea613a39565b5b6140f78a828b01614042565b95505060606141088a828b01613d4e565b94505060806141198a828b01613e31565b93505060a061412a8a828b01613d4e565b92505060c061413b8a828b01613d4e565b91505092959891949750929550565b6000602082840312156141605761415f613a34565b5b600082013567ffffffffffffffff81111561417e5761417d613a39565b5b61418a84828501614042565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006141ba82614193565b6141c4818561419e565b93506141d4818560208601613b15565b6141dd81613b3f565b840191505092915050565b6000602082019050818103600083015261420281846141af565b905092915050565b60008060008060008060c0878903121561422757614226613a34565b5b600087013567ffffffffffffffff81111561424557614244613a39565b5b61425189828a01614042565b965050602061426289828a01613bcc565b955050604061427389828a01613d4e565b945050606061428489828a01613e31565b935050608061429589828a01613d4e565b92505060a06142a689828a01613d4e565b9150509295509295509295565b60006142be82613eed565b9050919050565b6142ce816142b3565b82525050565b60006020820190506142e960008301846142c5565b92915050565b60006142fa82613eed565b9050919050565b61430a816142ef565b82525050565b60006020820190506143256000830184614301565b92915050565b61433481613ac3565b811461433f57600080fd5b50565b6000813590506143518161432b565b92915050565b6000806040838503121561436e5761436d613a34565b5b600061437c85828601613c81565b925050602061438d85828601614342565b9150509250929050565b600080600080608085870312156143b1576143b0613a34565b5b60006143bf87828801613c81565b94505060206143d087828801613c81565b93505060406143e187828801613bcc565b925050606085013567ffffffffffffffff81111561440257614401613a39565b5b61440e87828801614042565b91505092959194509250565b6000806040838503121561443157614430613a34565b5b600083013567ffffffffffffffff81111561444f5761444e613a39565b5b61445b85828601614042565b925050602083013567ffffffffffffffff81111561447c5761447b613a39565b5b61448885828601614042565b9150509250929050565b600080604083850312156144a9576144a8613a34565b5b60006144b785828601613c81565b92505060206144c885828601613c81565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061451957607f821691505b60208210810361452c5761452b6144d2565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061458e602183613b04565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b6000614620603e83613b04565b915061462b826145c4565b604082019050919050565b6000602082019050818103600083015261464f81614613565b9050919050565b600081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614697601c83614656565b91506146a282614661565b601c82019050919050565b6000819050919050565b6146c86146c382613d2d565b6146ad565b82525050565b60006146d98261468a565b91506146e582846146b7565b60208201915081905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614750602e83613b04565b915061475b826146f4565b604082019050919050565b6000602082019050818103600083015261477f81614743565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b60006147e2602b83613b04565b91506147ed82614786565b604082019050919050565b60006020820190508181036000830152614811816147d5565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b600061484e601f83613b04565b915061485982614818565b602082019050919050565b6000602082019050818103600083015261487d81614841565b9050919050565b600081905092915050565b50565b600061489f600083614884565b91506148aa8261488f565b600082019050919050565b60006148c082614892565b9150819050919050565b60008160601b9050919050565b60006148e2826148ca565b9050919050565b60006148f4826148d7565b9050919050565b61490c61490782613c2e565b6148e9565b82525050565b6000819050919050565b61492d61492882613bab565b614912565b82525050565b600061493f82856148fb565b60148201915061494f828461491c565b6020820191508190509392505050565b7f546865206d736748617368206973206e6f7420612068617368206f662074686560008201527f20746f6b656e49642e20204578706c61696e20796f757273656c662100000000602082015250565b60006149bb603c83613b04565b91506149c68261495f565b604082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b6149fa81613e0d565b82525050565b6000608082019050614a156000830187613d90565b614a2260208301866149f1565b614a2f6040830185613d90565b614a3c6060830184613d90565b95945050505050565b7f5468697320667265654d696e7420776173206e6f74207369676e65642062792060008201527f667265654d696e745369676e65722e2020486f7720656d626172617373696e6760208201527f2e00000000000000000000000000000000000000000000000000000000000000604082015250565b6000614ac7604183613b04565b9150614ad282614a45565b606082019050919050565b60006020820190508181036000830152614af681614aba565b9050919050565b7f546869732066726565206d696e742049442068617320616c726561647920626560008201527f656e2072656465656d6564000000000000000000000000000000000000000000602082015250565b6000614b59602b83613b04565b9150614b6482614afd565b604082019050919050565b60006020820190508181036000830152614b8881614b4c565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614beb602c83613b04565b9150614bf682614b8f565b604082019050919050565b60006020820190508181036000830152614c1a81614bde565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000614c86601883613b04565b9150614c9182614c50565b602082019050919050565b60006020820190508181036000830152614cb581614c79565b9050919050565b7f596f7520617265206e6f74207065726d697474656420746f206d696e74000000600082015250565b6000614cf2601d83613b04565b9150614cfd82614cbc565b602082019050919050565b60006020820190508181036000830152614d2181614ce5565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614d5d81613bab565b82525050565b6000614d6f8383614d54565b60208301905092915050565b6000602082019050919050565b6000614d9382614d28565b614d9d8185614d33565b9350614da883614d44565b8060005b83811015614dd9578151614dc08882614d63565b9750614dcb83614d7b565b925050600181019050614dac565b5085935050505092915050565b6000606082019050614dfb6000830186613cd6565b8181036020830152614e0d81856141af565b90508181036040830152614e218184614d88565b9050949350505050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000614e87602983613b04565b9150614e9282614e2b565b604082019050919050565b60006020820190508181036000830152614eb681614e7a565b9050919050565b7f54686973207075626b657920616c726561647920657869737473000000000000600082015250565b6000614ef3601a83613b04565b9150614efe82614ebd565b602082019050919050565b60006020820190508181036000830152614f2281614ee6565b9050919050565b7f596f75206d757374207061792065786163746c79206d696e7420636f73740000600082015250565b6000614f5f601e83613b04565b9150614f6a82614f29565b602082019050919050565b60006020820190508181036000830152614f8e81614f52565b9050919050565b6000606082019050614faa6000830186613cd6565b8181036020830152614fbc81856141af565b9050614fcb6040830184613c40565b949350505050565b600067ffffffffffffffff821115614fee57614fed613f45565b5b614ff782613b3f565b9050602081019050919050565b600061501761501284614fd3565b613fa5565b90508281526020810184848401111561503357615032613f40565b5b61503e848285613b15565b509392505050565b600082601f83011261505b5761505a613f3b565b5b815161506b848260208601615004565b91505092915050565b60006020828403121561508a57615089613a34565b5b600082015167ffffffffffffffff8111156150a8576150a7613a39565b5b6150b484828501615046565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615119602683613b04565b9150615124826150bd565b604082019050919050565b600060208201905081810360008301526151488161510c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615185602083613b04565b91506151908261514f565b602082019050919050565b600060208201905081810360008301526151b481615178565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000615217602583613b04565b9150615222826151bb565b604082019050919050565b600060208201905081810360008301526152468161520a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006152a9602483613b04565b91506152b48261524d565b604082019050919050565b600060208201905081810360008301526152d88161529c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061531982613bab565b915061532483613bab565b925082820390508181111561533c5761533b6152df565b5b92915050565b600061534d82613bab565b915061535883613bab565b92508282019050808211156153705761536f6152df565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026153d87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261539b565b6153e2868361539b565b95508019841693508086168417925050509392505050565b600061541561541061540b84613bab565b613ec1565b613bab565b9050919050565b6000819050919050565b61542f836153fa565b61544361543b8261541c565b8484546153a8565b825550505050565b600090565b61545861544b565b615463818484615426565b505050565b5b818110156154875761547c600082615450565b600181019050615469565b5050565b601f8211156154cc5761549d81615376565b6154a68461538b565b810160208510156154b5578190505b6154c96154c18561538b565b830182615468565b50505b505050565b600082821c905092915050565b60006154ef600019846008026154d1565b1980831691505092915050565b600061550883836154de565b9150826002028217905092915050565b61552182614193565b67ffffffffffffffff81111561553a57615539613f45565b5b6155448254614501565b61554f82828561548b565b600060209050601f8311600181146155825760008415615570578287015190505b61557a85826154fc565b8655506155e2565b601f19841661559086615376565b60005b828110156155b857848901518255600182019150602085019450602081019050615593565b868310156155d557848901516155d1601f8916826154de565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000615620601983613b04565b915061562b826155ea565b602082019050919050565b6000602082019050818103600083015261564f81615613565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006156b2603283613b04565b91506156bd82615656565b604082019050919050565b600060208201905081810360008301526156e1816156a5565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b600061571e600e83613b04565b9150615729826156e8565b602082019050919050565b6000602082019050818103600083015261574d81615711565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061578a601183613b04565b915061579582615754565b602082019050919050565b600060208201905081810360008301526157b98161577d565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006157f6602083613b04565b9150615801826157c0565b602082019050919050565b60006020820190508181036000830152615825816157e9565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615862601c83613b04565b915061586d8261582c565b602082019050919050565b6000602082019050818103600083015261589181615855565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006080820190506158dc6000830187613c40565b6158e96020830186613c40565b6158f66040830185613cd6565b818103606083015261590881846141af565b905095945050505050565b60008151905061592281613a6a565b92915050565b60006020828403121561593e5761593d613a34565b5b600061594c84828501615913565b9150509291505056fea264697066735822122050079be92fc9d5ddf7cbe0f0a8d11a189508222c82430d3903f337e939c0ee0164736f6c63430008110033","abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":true,"internalType":"address","name":"newFreeMintSigner","type":"address"}],"name":"FreeMintSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"MintCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterPermitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRevoked","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":"pkpNftMetadataAddress","type":"address"}],"name":"PkpNftMetadataAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"PkpPermissionsAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"}],"name":"PkpRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingAddress","type":"address"}],"name":"StakingAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"_getTokenIdToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"addPermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethAddressToPkpId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"freeMintId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"freeMintSigTest","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEthAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPubkey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"ipfsCID","type":"bytes"}],"name":"mintGrantAndBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNftMetadata","outputs":[{"internalType":"contract PKPNFTMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"prefixed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pubkeys","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemedFreeMintIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPermittedMinter","type":"address"}],"name":"removePermittedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"address","name":"newFreeMintSigner","type":"address"}],"name":"setFreeMintSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintCost","type":"uint256"}],"name":"setMintCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpNftMetadataAddress","type":"address"}],"name":"setPkpNftMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract Staking","name":"","type":"address"}],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/SoloNetPKPHelper.json b/deployments/rolluptestnet_987/SoloNetPKPHelper.json deleted file mode 100644 index 4278e1c..0000000 --- a/deployments/rolluptestnet_987/SoloNetPKPHelper.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/SoloNetPKPHelper.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { SoloNetPKP } from \\\"./SoloNetPKP.sol\\\";\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport { IERC721Receiver } from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\n\\n/// @title PKP Helper Contract\\n///\\n/// @dev This is the contract that helps minting PKPs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKPHelper is Ownable, IERC721Receiver {\\n /* ========== STATE VARIABLES ========== */\\n\\n SoloNetPKP public pkpNFT;\\n PKPPermissions public pkpPermissions;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft, address _pkpPermissions) {\\n pkpNFT = SoloNetPKP(_pkpNft);\\n pkpPermissions = PKPPermissions(_pkpPermissions);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintAndAddAuthMethods(\\n bytes memory pubkey,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n return\\n mintAndAddAuthMethodsWithTypes(\\n pubkey,\\n new bytes[](0), // permitted ipfs CIDs\\n new uint256[][](0), // permitted ipfs CIDs scopes\\n new address[](0), // permitted addresses\\n new uint256[][](0), // permitted addresses scopes\\n permittedAuthMethodTypes,\\n permittedAuthMethodIds,\\n permittedAuthMethodPubkeys,\\n permittedAuthMethodScopes,\\n addPkpEthAddressAsPermittedAddress,\\n sendPkpToItself\\n );\\n }\\n\\n function mintAndAddAuthMethodsWithTypes(\\n bytes memory pubkey,\\n bytes[] memory permittedIpfsCIDs,\\n uint256[][] memory permittedIpfsCIDScopes,\\n address[] memory permittedAddresses,\\n uint256[][] memory permittedAddressScopes,\\n uint256[] memory permittedAuthMethodTypes,\\n bytes[] memory permittedAuthMethodIds,\\n bytes[] memory permittedAuthMethodPubkeys,\\n uint256[][] memory permittedAuthMethodScopes,\\n bool addPkpEthAddressAsPermittedAddress,\\n bool sendPkpToItself\\n ) public payable returns (uint256) {\\n // mint the nft and forward the funds\\n uint256 tokenId = pkpNFT.mint{ value: msg.value }(pubkey);\\n\\n // sanity checking array lengths\\n require(\\n permittedIpfsCIDs.length == permittedIpfsCIDScopes.length,\\n \\\"PKPHelper: ipfs cid and scope array lengths must match\\\"\\n );\\n require(\\n permittedAddresses.length == permittedAddressScopes.length,\\n \\\"PKPHelper: address and scope array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodIds.length,\\n \\\"PKPHelper: auth method type and id array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length ==\\n permittedAuthMethodPubkeys.length,\\n \\\"PKPHelper: auth method type and pubkey array lengths must match\\\"\\n );\\n require(\\n permittedAuthMethodTypes.length == permittedAuthMethodScopes.length,\\n \\\"PKPHelper: auth method type and scopes array lengths must match\\\"\\n );\\n\\n // permit the action\\n if (permittedIpfsCIDs.length != 0) {\\n for (uint256 i = 0; i < permittedIpfsCIDs.length; i++) {\\n pkpPermissions.addPermittedAction(\\n tokenId,\\n permittedIpfsCIDs[i],\\n permittedIpfsCIDScopes[i]\\n );\\n }\\n }\\n\\n // permit the address\\n if (permittedAddresses.length != 0) {\\n for (uint256 i = 0; i < permittedAddresses.length; i++) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n permittedAddresses[i],\\n permittedAddressScopes[i]\\n );\\n }\\n }\\n\\n // permit the auth method\\n if (permittedAuthMethodTypes.length != 0) {\\n for (uint256 i = 0; i < permittedAuthMethodTypes.length; i++) {\\n pkpPermissions.addPermittedAuthMethod(\\n tokenId,\\n PKPPermissions.AuthMethod(\\n permittedAuthMethodTypes[i],\\n permittedAuthMethodIds[i],\\n permittedAuthMethodPubkeys[i]\\n ),\\n permittedAuthMethodScopes[i]\\n );\\n }\\n }\\n\\n address pkpEthAddress = pkpNFT.getEthAddress(tokenId);\\n\\n // add the pkp eth address as a permitted address\\n if (addPkpEthAddressAsPermittedAddress) {\\n pkpPermissions.addPermittedAddress(\\n tokenId,\\n pkpEthAddress,\\n new uint256[](0)\\n );\\n }\\n\\n if (sendPkpToItself) {\\n pkpNFT.safeTransferFrom(address(this), pkpEthAddress, tokenId);\\n } else {\\n pkpNFT.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = SoloNetPKP(newPkpNftAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address newPkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(newPkpPermissionsAddress);\\n }\\n\\n function onERC721Received(\\n address /* operator */,\\n address /* from */,\\n uint256 /* tokenId */,\\n bytes calldata /* data */\\n ) external view override returns (bytes4) {\\n // only accept transfers from the pkpNft contract\\n require(\\n msg.sender == address(pkpNFT),\\n \\\"PKPHelper: only accepts transfers from the PKPNFT contract\\\"\\n );\\n return this.onERC721Received.selector;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPNFT.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFT is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n /* ========== STATE VARIABLES ========== */\\n\\n PubkeyRouter public router;\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n\\n // maps keytype to array of unminted routed token ids\\n mapping(uint256 => uint256[]) public unmintedRoutedTokenIds;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return router.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return router.getPubkey(tokenId);\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC721, ERC721Enumerable)\\n returns (bool)\\n {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(uint256 tokenId)\\n public\\n view\\n override\\n returns (string memory)\\n {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = router.getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = router.getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n function getUnmintedRoutedTokenIdCount(uint256 keyType)\\n public\\n view\\n returns (uint256)\\n {\\n return unmintedRoutedTokenIds[keyType].length;\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mintNext(uint256 keyType) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurnNext(uint256 keyType, bytes memory ipfsCID)\\n public\\n payable\\n returns (uint256)\\n {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMintNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMint(freeMintId, tokenId, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurnNext(\\n uint256 keyType,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n uint256 tokenId = _getNextTokenIdToMint(keyType);\\n freeMintGrantAndBurn(freeMintId, tokenId, ipfsCID, msgHash, v, r, s);\\n return tokenId;\\n }\\n\\n /// create a valid token for a given public key.\\n function mintSpecific(uint256 tokenId) public onlyOwner {\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n }\\n\\n /// mint a PKP, grant access to a Lit Action, and then burn the PKP\\n /// this happens in a single txn, so it's provable that only that lit action\\n /// has ever had access to use the PKP.\\n /// this is useful in the context of something like a \\\"prime number certification lit action\\\"\\n /// where you could just trust the sig that a number is prime.\\n /// without this function, a user could mint a PKP, sign a bunch of junk, and then burn the\\n /// PKP to make it looks like only the Lit Action can use it.\\n function mintGrantAndBurnSpecific(uint256 tokenId, bytes memory ipfsCID)\\n public\\n onlyOwner\\n {\\n _mintWithoutValueCheck(tokenId, address(this));\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function freeMint(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n }\\n\\n function freeMintGrantAndBurn(\\n uint256 freeMintId,\\n uint256 tokenId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n _mintWithoutValueCheck(tokenId, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n }\\n\\n function _mintWithoutValueCheck(uint256 tokenId, address to) internal {\\n require(router.isRouted(tokenId), \\\"This PKP has not been routed yet\\\");\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n }\\n\\n /// Take a tokenId off the stack\\n function _getNextTokenIdToMint(uint256 keyType) internal returns (uint256) {\\n require(\\n unmintedRoutedTokenIds[keyType].length > 0,\\n \\\"There are no unminted routed token ids to mint\\\"\\n );\\n uint256 tokenId = unmintedRoutedTokenIds[keyType][\\n unmintedRoutedTokenIds[keyType].length - 1\\n ];\\n\\n unmintedRoutedTokenIds[keyType].pop();\\n\\n return tokenId;\\n }\\n\\n function setRouterAddress(address routerAddress) public onlyOwner {\\n router = PubkeyRouter(routerAddress);\\n emit RouterAddressSet(routerAddress);\\n }\\n\\n function setPkpNftMetadataAddress(address pkpNftMetadataAddress)\\n public\\n onlyOwner\\n {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(address pkpPermissionsAddress)\\n public\\n onlyOwner\\n {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /// Push a tokenId onto the stack\\n function pkpRouted(uint256 tokenId, uint256 keyType) public {\\n require(\\n msg.sender == address(router),\\n \\\"Only the routing contract can call this function\\\"\\n );\\n unmintedRoutedTokenIds[keyType].push(tokenId);\\n emit PkpRouted(tokenId, keyType);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event RouterAddressSet(address indexed routerAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"solidity-bytes-utils/contracts/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gonçalo Sá \\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\npragma solidity >=0.8.0 <0.9.0;\\n\\n\\nlibrary BytesLib {\\n function concat(\\n bytes memory _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(0x40, and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n ))\\n }\\n\\n return tempBytes;\\n }\\n\\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n assembly {\\n // Read the first 32 bytes of _preBytes storage, which is the length\\n // of the array. (We don't need to use the offset into the slot\\n // because arrays use the entire slot.)\\n let fslot := sload(_preBytes.slot)\\n // Arrays of 31 bytes or less have an even value in their slot,\\n // while longer arrays have an odd value. The actual length is\\n // the slot divided by two for odd values, and the lowest order\\n // byte divided by two for even values.\\n // If the slot is even, bitwise and the slot with 255 and divide by\\n // two to get the length. If the slot is odd, bitwise and the slot\\n // with -1 and divide by two.\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n let newlength := add(slength, mlength)\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n switch add(lt(slength, 32), lt(newlength, 32))\\n case 2 {\\n // Since the new array still fits in the slot, we just need to\\n // update the contents of the slot.\\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n sstore(\\n _preBytes.slot,\\n // all the modifications to the slot are inside this\\n // next block\\n add(\\n // we can just add to the slot contents because the\\n // bytes we want to change are the LSBs\\n fslot,\\n add(\\n mul(\\n div(\\n // load the bytes from memory\\n mload(add(_postBytes, 0x20)),\\n // zero all bytes to the right\\n exp(0x100, sub(32, mlength))\\n ),\\n // and now shift left the number of bytes to\\n // leave space for the length in the slot\\n exp(0x100, sub(32, newlength))\\n ),\\n // increase length by the double of the memory\\n // bytes length\\n mul(mlength, 2)\\n )\\n )\\n )\\n }\\n case 1 {\\n // The stored value fits in the slot, but the combined value\\n // will exceed it.\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // The contents of the _postBytes array start 32 bytes into\\n // the structure. Our first read should obtain the `submod`\\n // bytes that can fit into the unused space in the last word\\n // of the stored array. To get this, we read 32 bytes starting\\n // from `submod`, so the data we read overlaps with the array\\n // contents by `submod` bytes. Masking the lowest-order\\n // `submod` bytes allows us to add that value directly to the\\n // stored value.\\n\\n let submod := sub(32, slength)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(\\n sc,\\n add(\\n and(\\n fslot,\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\\n ),\\n and(mload(mc), mask)\\n )\\n )\\n\\n for {\\n mc := add(mc, 0x20)\\n sc := add(sc, 1)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n default {\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n // Start copying to the last used word of the stored array.\\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n // save new length\\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n // Copy over the first `submod` bytes of the new data as in\\n // case 1 above.\\n let slengthmod := mod(slength, 32)\\n let mlengthmod := mod(mlength, 32)\\n let submod := sub(32, slengthmod)\\n let mc := add(_postBytes, submod)\\n let end := add(_postBytes, mlength)\\n let mask := sub(exp(0x100, submod), 1)\\n\\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n for {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } lt(mc, end) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n sstore(sc, mload(mc))\\n }\\n\\n mask := exp(0x100, sub(mc, end))\\n\\n sstore(sc, mul(div(mload(mc), mask), mask))\\n }\\n }\\n }\\n\\n function slice(\\n bytes memory _bytes,\\n uint256 _start,\\n uint256 _length\\n )\\n internal\\n pure\\n returns (bytes memory)\\n {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n\\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n address tempAddress;\\n\\n assembly {\\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n }\\n\\n return tempAddress;\\n }\\n\\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n require(_bytes.length >= _start + 1 , \\\"toUint8_outOfBounds\\\");\\n uint8 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x1), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n uint16 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x2), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n uint32 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x4), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n uint64 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x8), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n uint96 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0xc), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n uint128 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x10), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n uint256 tempUint;\\n\\n assembly {\\n tempUint := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempUint;\\n }\\n\\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n bytes32 tempBytes32;\\n\\n assembly {\\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n }\\n\\n return tempBytes32;\\n }\\n\\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n bool success = true;\\n\\n assembly {\\n let length := mload(_preBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(length, mload(_postBytes))\\n case 1 {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n let mc := add(_preBytes, 0x20)\\n let end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n } eq(add(lt(mc, end), cb), 2) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // if any of these checks fails then arrays are not equal\\n if iszero(eq(mload(mc), mload(cc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n\\n function equalStorage(\\n bytes storage _preBytes,\\n bytes memory _postBytes\\n )\\n internal\\n view\\n returns (bool)\\n {\\n bool success = true;\\n\\n assembly {\\n // we know _preBytes_offset is 0\\n let fslot := sload(_preBytes.slot)\\n // Decode the length of the stored array like in concatStorage().\\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n let mlength := mload(_postBytes)\\n\\n // if lengths don't match the arrays are not equal\\n switch eq(slength, mlength)\\n case 1 {\\n // slength can contain both the length and contents of the array\\n // if length < 32 bytes so let's prepare for that\\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n if iszero(iszero(slength)) {\\n switch lt(slength, 32)\\n case 1 {\\n // blank the last byte which is the length\\n fslot := mul(div(fslot, 0x100), 0x100)\\n\\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n // unsuccess:\\n success := 0\\n }\\n }\\n default {\\n // cb is a circuit breaker in the for loop since there's\\n // no said feature for inline assembly loops\\n // cb = 1 - don't breaker\\n // cb = 0 - break\\n let cb := 1\\n\\n // get the keccak hash to get the contents of the array\\n mstore(0x0, _preBytes.slot)\\n let sc := keccak256(0x0, 0x20)\\n\\n let mc := add(_postBytes, 0x20)\\n let end := add(mc, mlength)\\n\\n // the next line is the loop condition:\\n // while(uint256(mc < end) + cb == 2)\\n for {} eq(add(lt(mc, end), cb), 2) {\\n sc := add(sc, 1)\\n mc := add(mc, 0x20)\\n } {\\n if iszero(eq(sload(sc), mload(mc))) {\\n // unsuccess:\\n success := 0\\n cb := 0\\n }\\n }\\n }\\n }\\n }\\n default {\\n // unsuccess:\\n success := 0\\n }\\n }\\n\\n return success;\\n }\\n}\\n\",\"versionPragma\":\">=0.8.0 <0.9.0\"},\"contracts/PubkeyRouter.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: make the tests send PKPNFT into the constructor\\n// TODO: test interaction between PKPNFT and this contract, like mint a keypair and see if you can access it\\n// TODO: setRoutingData() for a batch of keys\\n\\ncontract PubkeyRouter is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n struct PubkeyRoutingData {\\n bytes pubkey;\\n address stakingContract;\\n uint256 keyType; // 1 = BLS, 2 = ECDSA. Not doing this in an enum so we can add more keytypes in the future without redeploying.\\n }\\n\\n struct PubkeyRegistrationProgress {\\n PubkeyRoutingData routingData;\\n uint256 nodeVoteCount;\\n uint256 nodeVoteThreshold;\\n mapping(address => bool) votedNodes;\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> PubkeyRoutingData\\n mapping(uint256 => PubkeyRoutingData) public pubkeys;\\n\\n // this is used to count the votes from the nodes to register a key\\n // map the keccack256(uncompressed pubkey) -> PubkeyRegistrationProgress\\n mapping(uint256 => PubkeyRegistrationProgress) public pubkeyRegistrations;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the routing data for a given key hash\\n function getRoutingData(uint256 tokenId)\\n external\\n view\\n returns (PubkeyRoutingData memory)\\n {\\n return pubkeys[tokenId];\\n }\\n\\n /// get if a given pubkey has routing data associated with it or not\\n function isRouted(uint256 tokenId) public view returns (bool) {\\n PubkeyRoutingData memory prd = pubkeys[tokenId];\\n return\\n prd.pubkey.length != 0 &&\\n prd.keyType != 0 &&\\n prd.stakingContract != address(0);\\n }\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // only return addresses for ECDSA keys so that people don't\\n // send funds to a BLS key that would be irretrieveably lost\\n if (pubkeys[tokenId].keyType != 2) {\\n return address(0);\\n }\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].pubkey.slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId].pubkey;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Set the pubkey and routing data for a given key hash\\n // this is only used by an admin in case of emergency. can prob be removed.\\n function setRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public onlyOwner {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(tokenId, pubkey, stakingContract, keyType);\\n }\\n\\n /// vote to set the pubkey and routing data for a given key\\n // FIXME this is vulnerable to an attack where the first node to call setRoutingData can set an incorrect stakingContract, or keyType, since none of those are validated. Then, if more nodes try to call setRoutingData with the correct data, it will revert because it doesn't match. Instead, it should probably be vote based. so if 1 guy votes for an incorrect keyLength, it doesn't matter, because the one that gets the most votes wins.\\n // FIXME this is also vulnerable to an attack where someone sets up their own staking contract with a threshold of 1 and then goes around claiming tokenIds and filling them with junk. we probably need to verify that the staking contract is legit. i'm not sure how to do that though. like we can check various things from the staking contract, that the staked token is the real Lit token, and that the user has staked a significant amount. But how do we know that staking contract isn't a custom fork that lies about all that stuff? Maybe we need a mapping of valid staking contracts somewhere, and when we deploy a new one we add it manually.\\n function voteForRoutingData(\\n uint256 tokenId,\\n bytes memory pubkey,\\n address stakingContract,\\n uint256 keyType\\n ) public {\\n // check that the sender is a staking node and hasn't already voted for this key\\n Staking stakingContractInstance = Staking(stakingContract);\\n address stakerAddress = stakingContractInstance\\n .nodeAddressToStakerAddress(msg.sender);\\n require(\\n stakingContractInstance.isActiveValidator(stakerAddress),\\n \\\"Only active validators can set routing data\\\"\\n );\\n\\n require(\\n !pubkeyRegistrations[tokenId].votedNodes[msg.sender],\\n \\\"You have already voted for this key\\\"\\n );\\n\\n // if this is the first registration, validate that the hashes match\\n if (pubkeyRegistrations[tokenId].nodeVoteCount == 0) {\\n // this is the only place where the tokenId could become decoupled from the pubkey.\\n // therefore, we need to ensure that the tokenId was derived correctly\\n // this only needs to be done the first time the PKP is registered\\n\\n require(\\n tokenId == uint256(keccak256(pubkey)),\\n \\\"tokenId does not match hashed keyParts\\\"\\n );\\n pubkeyRegistrations[tokenId].routingData.pubkey = pubkey;\\n pubkeyRegistrations[tokenId]\\n .routingData\\n .stakingContract = stakingContract;\\n pubkeyRegistrations[tokenId].routingData.keyType = keyType;\\n\\n // set the threshold of votes to be the threshold of validators in the staking contract\\n pubkeyRegistrations[tokenId]\\n .nodeVoteThreshold = stakingContractInstance\\n .validatorCountForConsensus();\\n } else {\\n // if this is not the first registration, validate that everything matches\\n require(\\n pubkey.length ==\\n pubkeyRegistrations[tokenId].routingData.pubkey.length &&\\n keccak256(pubkey) ==\\n keccak256(pubkeyRegistrations[tokenId].routingData.pubkey),\\n \\\"pubkey does not match previous registrations\\\"\\n );\\n\\n // validate that the staking contract matches\\n require(\\n stakingContract ==\\n pubkeyRegistrations[tokenId].routingData.stakingContract,\\n \\\"stakingContract does not match\\\"\\n );\\n\\n // validate that the key type matches\\n require(\\n keyType == pubkeyRegistrations[tokenId].routingData.keyType,\\n \\\"keyType does not match\\\"\\n );\\n }\\n\\n pubkeyRegistrations[tokenId].votedNodes[msg.sender] = true;\\n pubkeyRegistrations[tokenId].nodeVoteCount++;\\n emit PubkeyRoutingDataVote(\\n tokenId,\\n msg.sender,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n\\n // if nodeVoteCount is greater than nodeVoteThreshold, set the routing data\\n if (\\n pubkeyRegistrations[tokenId].nodeVoteCount >\\n pubkeyRegistrations[tokenId].nodeVoteThreshold &&\\n !isRouted(tokenId)\\n ) {\\n pubkeys[tokenId].pubkey = pubkey;\\n pubkeys[tokenId].stakingContract = stakingContract;\\n pubkeys[tokenId].keyType = keyType;\\n\\n // if this is an ECSDA key, then store the eth address reverse mapping\\n if (keyType == 2) {\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n }\\n\\n pkpNFT.pkpRouted(tokenId, keyType);\\n\\n emit PubkeyRoutingDataSet(\\n tokenId,\\n pubkey,\\n stakingContract,\\n keyType\\n );\\n }\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n emit PkpNftAddressSet(newPkpNftAddress);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PubkeyRoutingDataSet(\\n uint256 indexed tokenId,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n event PubkeyRoutingDataVote(\\n uint256 indexed tokenId,\\n address indexed nodeAddress,\\n bytes pubkey,\\n address stakingContract,\\n uint256 keyType\\n );\\n\\n event PkpNftAddressSet(address newPkpNftAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"contracts/PKPPermissions.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { BitMaps } from \\\"@openzeppelin/contracts/utils/structs/BitMaps.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\\\";\\n\\nimport { PKPNFT } from \\\"./PKPNFT.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract PKPPermissions is Ownable {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n using EnumerableSet for EnumerableSet.UintSet;\\n using BytesLib for bytes;\\n using BitMaps for BitMaps.BitMap;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPNFT public pkpNFT;\\n\\n enum AuthMethodType {\\n NULLMETHOD, // 0\\n ADDRESS, // 1\\n ACTION, // 2\\n WEBAUTHN, // 3\\n DISCORD, // 4\\n GOOGLE, // 5\\n GOOGLE_JWT // 6\\n }\\n\\n struct AuthMethod {\\n uint256 authMethodType; // 1 = address, 2 = action, 3 = WebAuthn, 4 = Discord, 5 = Google, 6 = Google JWT. Not doing this in an enum so that we can add more auth methods in the future without redeploying.\\n bytes id; // the id of the auth method. For address, this is an eth address. For action, this is an IPFS CID. For WebAuthn, this is the credentialId. For Discord, this is the user's Discord ID. For Google, this is the user's Google ID.\\n bytes userPubkey; // the user's pubkey. This is used for WebAuthn.\\n }\\n\\n // map the keccack256(uncompressed pubkey) -> set of auth methods\\n mapping(uint256 => EnumerableSet.UintSet) permittedAuthMethods;\\n\\n // map the keccack256(uncompressed pubkey) -> auth_method_id -> scope id\\n mapping(uint256 => mapping(uint256 => BitMaps.BitMap)) permittedAuthMethodScopes;\\n\\n // map the keccack256(authMethodType, userId) -> the actual AuthMethod struct\\n mapping(uint256 => AuthMethod) public authMethods;\\n\\n // map the AuthMethod hash to the pubkeys that it's allowed to sign for\\n // this makes it possible to be given a discord id and then lookup all the pubkeys that are allowed to sign for that discord id\\n mapping(uint256 => EnumerableSet.UintSet) authMethodToPkpIds;\\n\\n // map the keccack256(uncompressed pubkey) -> (group => merkle tree root hash)\\n mapping(uint256 => mapping(uint256 => bytes32)) private _rootHashes;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _pkpNft) {\\n pkpNFT = PKPNFT(_pkpNft);\\n }\\n\\n /* ========== Modifier ========== */\\n modifier onlyPKPOwner(uint256 tokenId) {\\n // check that user is allowed to set this\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n require(msg.sender == nftOwner, \\\"Not PKP NFT owner\\\");\\n _;\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair, as long as it's an ecdsa keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n return pkpNFT.getEthAddress(tokenId);\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pkpNFT.getPubkey(tokenId);\\n }\\n\\n function getAuthMethodId(\\n uint256 authMethodType,\\n bytes memory id\\n ) public pure returns (uint256) {\\n return uint256(keccak256(abi.encode(authMethodType, id)));\\n }\\n\\n /// get the user's pubkey given their authMethodType and userId\\n function getUserPubkeyForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (bytes memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n AuthMethod memory am = authMethods[authMethodId];\\n return am.userPubkey;\\n }\\n\\n function getTokenIdsForAuthMethod(\\n uint256 authMethodType,\\n bytes calldata id\\n ) external view returns (uint256[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n uint256 pkpIdsLength = authMethodToPkpIds[authMethodId].length();\\n uint256[] memory allPkpIds = new uint256[](pkpIdsLength);\\n\\n for (uint256 i = 0; i < pkpIdsLength; i++) {\\n allPkpIds[i] = authMethodToPkpIds[authMethodId].at(i);\\n }\\n\\n return allPkpIds;\\n }\\n\\n function getPermittedAuthMethods(\\n uint256 tokenId\\n ) external view returns (AuthMethod[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n AuthMethod[] memory allPermittedAuthMethods = new AuthMethod[](\\n permittedAuthMethodsLength\\n );\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n allPermittedAuthMethods[i] = authMethods[authMethodHash];\\n }\\n\\n return allPermittedAuthMethods;\\n }\\n\\n function getPermittedAuthMethodScopes(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 maxScopeId\\n ) public view returns (bool[] memory) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n BitMaps.BitMap\\n storage permittedScopesBitMap = permittedAuthMethodScopes[tokenId][\\n authMethodId\\n ];\\n bool[] memory allScopes = new bool[](maxScopeId);\\n\\n for (uint256 i = 0; i < maxScopeId; i++) {\\n allScopes[i] = permittedScopesBitMap.get(i);\\n }\\n\\n return allScopes;\\n }\\n\\n function getPermittedActions(\\n uint256 tokenId\\n ) public view returns (bytes[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are actions\\n uint256 permittedActionsLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n permittedActionsLength++;\\n }\\n }\\n\\n bytes[] memory allPermittedActions = new bytes[](\\n permittedActionsLength\\n );\\n\\n uint256 permittedActionsIndex = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ACTION)) {\\n allPermittedActions[permittedActionsIndex] = am.id;\\n permittedActionsIndex++;\\n }\\n }\\n\\n return allPermittedActions;\\n }\\n\\n function getPermittedAddresses(\\n uint256 tokenId\\n ) public view returns (address[] memory) {\\n uint256 permittedAuthMethodsLength = permittedAuthMethods[tokenId]\\n .length();\\n\\n // count the number of auth methods that are addresses\\n uint256 permittedAddressLength = 0;\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n permittedAddressLength++;\\n }\\n }\\n\\n bool tokenExists = pkpNFT.exists(tokenId);\\n address[] memory allPermittedAddresses;\\n uint256 permittedAddressIndex = 0;\\n if (tokenExists) {\\n // token is not burned, so add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength + 1);\\n\\n // always add nft owner in first slot\\n address nftOwner = pkpNFT.ownerOf(tokenId);\\n allPermittedAddresses[0] = nftOwner;\\n permittedAddressIndex++;\\n } else {\\n // token is burned, so don't add the owner address\\n allPermittedAddresses = new address[](permittedAddressLength);\\n }\\n\\n for (uint256 i = 0; i < permittedAuthMethodsLength; i++) {\\n uint256 authMethodHash = permittedAuthMethods[tokenId].at(i);\\n AuthMethod memory am = authMethods[authMethodHash];\\n if (am.authMethodType == uint256(AuthMethodType.ADDRESS)) {\\n address parsed;\\n bytes memory id = am.id;\\n\\n // address was packed using abi.encodedPacked(address), so you need to pad left to get the correct bytes back\\n assembly {\\n parsed := div(\\n mload(add(id, 32)),\\n 0x1000000000000000000000000\\n )\\n }\\n allPermittedAddresses[permittedAddressIndex] = parsed;\\n permittedAddressIndex++;\\n }\\n }\\n\\n return allPermittedAddresses;\\n }\\n\\n /// get if a user is permitted to use a given pubkey. returns true if it is permitted to use the pubkey in the permittedAuthMethods[tokenId] struct.\\n function isPermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool permitted = permittedAuthMethods[tokenId].contains(authMethodId);\\n if (!permitted) {\\n return false;\\n }\\n return true;\\n }\\n\\n function isPermittedAuthMethodScopePresent(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public view returns (bool) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n bool present = permittedAuthMethodScopes[tokenId][authMethodId].get(\\n scopeId\\n );\\n return present;\\n }\\n\\n function isPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function isPermittedAddress(\\n uint256 tokenId,\\n address user\\n ) public view returns (bool) {\\n return\\n isPermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n ) || pkpNFT.ownerOf(tokenId) == user;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Add a permitted auth method for a given pubkey\\n function addPermittedAuthMethod(\\n uint256 tokenId,\\n AuthMethod memory authMethod,\\n uint256[] calldata scopes\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(\\n authMethod.authMethodType,\\n authMethod.id\\n );\\n\\n // we need to ensure that someone with the same auth method type and id can't add a different pubkey\\n require(\\n authMethods[authMethodId].userPubkey.length == 0 ||\\n keccak256(authMethods[authMethodId].userPubkey) ==\\n keccak256(authMethod.userPubkey),\\n \\\"Cannot add a different pubkey for the same auth method type and id\\\"\\n );\\n\\n authMethods[authMethodId] = authMethod;\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.add(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.add(tokenId);\\n\\n for (uint256 i = 0; i < scopes.length; i++) {\\n uint256 scopeId = scopes[i];\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(\\n tokenId,\\n authMethodId,\\n authMethod.id,\\n scopeId\\n );\\n }\\n\\n emit PermittedAuthMethodAdded(\\n tokenId,\\n authMethod.authMethodType,\\n authMethod.id,\\n authMethod.userPubkey\\n );\\n }\\n\\n // Remove a permitted auth method for a given pubkey\\n function removePermittedAuthMethod(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes memory id\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n EnumerableSet.UintSet\\n storage newPermittedAuthMethods = permittedAuthMethods[tokenId];\\n newPermittedAuthMethods.remove(authMethodId);\\n\\n EnumerableSet.UintSet storage newPkpIds = authMethodToPkpIds[\\n authMethodId\\n ];\\n newPkpIds.remove(tokenId);\\n\\n emit PermittedAuthMethodRemoved(tokenId, authMethodId, id);\\n }\\n\\n function addPermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].set(scopeId);\\n\\n emit PermittedAuthMethodScopeAdded(tokenId, authMethodId, id, scopeId);\\n }\\n\\n function removePermittedAuthMethodScope(\\n uint256 tokenId,\\n uint256 authMethodType,\\n bytes calldata id,\\n uint256 scopeId\\n ) public onlyPKPOwner(tokenId) {\\n uint256 authMethodId = getAuthMethodId(authMethodType, id);\\n\\n permittedAuthMethodScopes[tokenId][authMethodId].unset(scopeId);\\n\\n emit PermittedAuthMethodScopeRemoved(\\n tokenId,\\n authMethodType,\\n id,\\n scopeId\\n );\\n }\\n\\n /// Add a permitted action for a given pubkey\\n function addPermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(uint256(AuthMethodType.ACTION), ipfsCID, \\\"\\\"),\\n scopes\\n );\\n }\\n\\n function removePermittedAction(\\n uint256 tokenId,\\n bytes calldata ipfsCID\\n ) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ACTION),\\n ipfsCID\\n );\\n }\\n\\n function addPermittedAddress(\\n uint256 tokenId,\\n address user,\\n uint256[] calldata scopes\\n ) public {\\n addPermittedAuthMethod(\\n tokenId,\\n AuthMethod(\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user),\\n \\\"\\\"\\n ),\\n scopes\\n );\\n }\\n\\n function removePermittedAddress(uint256 tokenId, address user) public {\\n removePermittedAuthMethod(\\n tokenId,\\n uint256(AuthMethodType.ADDRESS),\\n abi.encodePacked(user)\\n );\\n }\\n\\n function setPkpNftAddress(address newPkpNftAddress) public onlyOwner {\\n pkpNFT = PKPNFT(newPkpNftAddress);\\n }\\n\\n /**\\n * Update the root hash of the merkle tree representing off-chain states for the PKP\\n */\\n function setRootHash(\\n uint256 tokenId,\\n uint256 group,\\n bytes32 root\\n ) public onlyPKPOwner(tokenId) {\\n _rootHashes[tokenId][group] = root;\\n emit RootHashUpdated(tokenId, group, root);\\n }\\n\\n /**\\n * Verify the given leaf existing in the merkle tree\\n */\\n function verifyState(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bytes32 leaf\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.verify(proof, root, leaf);\\n }\\n\\n /**\\n * Verify the given leaves existing in the merkle tree\\n */\\n function verifyStates(\\n uint256 tokenId,\\n uint256 group,\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) public view returns (bool) {\\n bytes32 root = _rootHashes[tokenId][group];\\n if (root == bytes32(0)) return false;\\n return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event PermittedAuthMethodAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n bytes userPubkey\\n );\\n event PermittedAuthMethodRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id\\n );\\n event PermittedAuthMethodScopeAdded(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event PermittedAuthMethodScopeRemoved(\\n uint256 indexed tokenId,\\n uint256 authMethodType,\\n bytes id,\\n uint256 scopeId\\n );\\n event RootHashUpdated(\\n uint256 indexed tokenId,\\n uint256 indexed group,\\n bytes32 root\\n );\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@openzeppelin/contracts/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n *\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE = \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n string memory result = new string(4 * ((data.length + 2) / 3));\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n\\n // When data `bytes` is not exactly 3 bytes long\\n // it is padded with `=` characters at the end\\n switch mod(mload(data), 3)\\n case 1 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n mstore8(sub(resultPtr, 2), 0x3d)\\n }\\n case 2 {\\n mstore8(sub(resultPtr, 1), 0x3d)\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/PKPNFTMetadata.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { Base64 } from \\\"@openzeppelin/contracts/utils/Base64.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n/// @title Programmable Keypair NFT Metadata\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract PKPNFTMetadata {\\n using Strings for uint256;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {}\\n\\n /* ========== VIEWS ========== */\\n\\n function bytesToHex(bytes memory buffer)\\n public\\n pure\\n returns (string memory)\\n {\\n // Fixed buffer size for hexadecimal convertion\\n bytes memory converted = new bytes(buffer.length * 2);\\n\\n bytes memory _base = \\\"0123456789abcdef\\\";\\n\\n for (uint256 i = 0; i < buffer.length; i++) {\\n converted[i * 2] = _base[uint8(buffer[i]) / _base.length];\\n converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];\\n }\\n\\n return string(abi.encodePacked(\\\"0x\\\", converted));\\n }\\n\\n function tokenURI(\\n uint256 tokenId,\\n bytes memory pubKey,\\n address ethAddress\\n ) public pure returns (string memory) {\\n string\\n memory svgData = \\\"\\\";\\n\\n string memory pubkeyStr = bytesToHex(pubKey);\\n // console.log(\\\"pubkeyStr\\\");\\n // console.log(pubkeyStr);\\n\\n string memory ethAddressStr = Strings.toHexString(ethAddress);\\n // console.log(\\\"ethAddressStr\\\");\\n // console.log(ethAddressStr);\\n\\n string memory tokenIdStr = Strings.toString(tokenId);\\n\\n string memory json = Base64.encode(\\n bytes(\\n string(\\n abi.encodePacked(\\n '{\\\"name\\\": \\\"Lit PKP #',\\n tokenIdStr,\\n '\\\", \\\"description\\\": \\\"This NFT entitles the holder to use a Lit Protocol PKP, and to grant access to other users and Lit Actions to use this PKP\\\", \\\"image_data\\\": \\\"',\\n bytes(svgData),\\n '\\\",\\\"attributes\\\": [{\\\"trait_type\\\": \\\"Public Key\\\", \\\"value\\\": \\\"',\\n pubkeyStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"ETH Wallet Address\\\", \\\"value\\\": \\\"',\\n ethAddressStr,\\n '\\\"}, {\\\"trait_type\\\": \\\"Token ID\\\", \\\"value\\\": \\\"',\\n tokenIdStr,\\n '\\\"}]}'\\n )\\n )\\n )\\n );\\n return string(abi.encodePacked(\\\"data:application/json;base64,\\\", json));\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor 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(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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 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 _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) 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);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` 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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) 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.\\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(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721Burnable is Context, ERC721 {\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/BitMaps.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.\\n * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].\\n */\\nlibrary BitMaps {\\n struct BitMap {\\n mapping(uint256 => uint256) _data;\\n }\\n\\n /**\\n * @dev Returns whether the bit at `index` is set.\\n */\\n function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n return bitmap._data[bucket] & mask != 0;\\n }\\n\\n /**\\n * @dev Sets the bit at `index` to the boolean `value`.\\n */\\n function setTo(\\n BitMap storage bitmap,\\n uint256 index,\\n bool value\\n ) internal {\\n if (value) {\\n set(bitmap, index);\\n } else {\\n unset(bitmap, index);\\n }\\n }\\n\\n /**\\n * @dev Sets the bit at `index`.\\n */\\n function set(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] |= mask;\\n }\\n\\n /**\\n * @dev Unsets the bit at `index`.\\n */\\n function unset(BitMap storage bitmap, uint256 index) internal {\\n uint256 bucket = index >> 8;\\n uint256 mask = 1 << (index & 0xff);\\n bitmap._data[bucket] &= ~mask;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev These functions deal with verification of Merkle Tree proofs.\\n *\\n * The proofs can be generated using the JavaScript library\\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\\n *\\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\\n *\\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\\n * hashing, or use a hash function other than keccak256 for hashing leaves.\\n * This is because the concatenation of a sorted pair of internal nodes in\\n * the merkle tree could be reinterpreted as a leaf value.\\n */\\nlibrary MerkleProof {\\n /**\\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\\n * defined by `root`. For this, a `proof` must be provided, containing\\n * sibling hashes on the branch from the leaf to the root of the tree. Each\\n * pair of leaves and each pair of pre-images are assumed to be sorted.\\n */\\n function verify(\\n bytes32[] memory proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProof(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {verify}\\n *\\n * _Available since v4.7._\\n */\\n function verifyCalldata(\\n bytes32[] calldata proof,\\n bytes32 root,\\n bytes32 leaf\\n ) internal pure returns (bool) {\\n return processProofCalldata(proof, leaf) == root;\\n }\\n\\n /**\\n * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\\n * hash matches the root of the tree. When processing the proof, the pairs\\n * of leafs & pre-images are assumed to be sorted.\\n *\\n * _Available since v4.4._\\n */\\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Calldata version of {processProof}\\n *\\n * _Available since v4.7._\\n */\\n function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\\n bytes32 computedHash = leaf;\\n for (uint256 i = 0; i < proof.length; i++) {\\n computedHash = _hashPair(computedHash, proof[i]);\\n }\\n return computedHash;\\n }\\n\\n /**\\n * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by\\n * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerify(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProof(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Calldata version of {multiProofVerify}\\n *\\n * _Available since v4.7._\\n */\\n function multiProofVerifyCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32 root,\\n bytes32[] memory leaves\\n ) internal pure returns (bool) {\\n return processMultiProofCalldata(proof, proofFlags, leaves) == root;\\n }\\n\\n /**\\n * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,\\n * consuming from one or the other at each step according to the instructions given by\\n * `proofFlags`.\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProof(\\n bytes32[] memory proof,\\n bool[] memory proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n /**\\n * @dev Calldata version of {processMultiProof}\\n *\\n * _Available since v4.7._\\n */\\n function processMultiProofCalldata(\\n bytes32[] calldata proof,\\n bool[] calldata proofFlags,\\n bytes32[] memory leaves\\n ) internal pure returns (bytes32 merkleRoot) {\\n // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by\\n // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\\n // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\\n // the merkle tree.\\n uint256 leavesLen = leaves.length;\\n uint256 totalHashes = proofFlags.length;\\n\\n // Check proof validity.\\n require(leavesLen + proof.length - 1 == totalHashes, \\\"MerkleProof: invalid multiproof\\\");\\n\\n // The xxxPos values are \\\"pointers\\\" to the next value to consume in each array. All accesses are done using\\n // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \\\"pop\\\".\\n bytes32[] memory hashes = new bytes32[](totalHashes);\\n uint256 leafPos = 0;\\n uint256 hashPos = 0;\\n uint256 proofPos = 0;\\n // At each step, we compute the next hash using two values:\\n // - a value from the \\\"main queue\\\". If not all leaves have been consumed, we get the next leaf, otherwise we\\n // get the next hash.\\n // - depending on the flag, either another value for the \\\"main queue\\\" (merging branches) or an element from the\\n // `proof` array.\\n for (uint256 i = 0; i < totalHashes; i++) {\\n bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\\n bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];\\n hashes[i] = _hashPair(a, b);\\n }\\n\\n if (totalHashes > 0) {\\n return hashes[totalHashes - 1];\\n } else if (leavesLen > 0) {\\n return leaves[0];\\n } else {\\n return proof[0];\\n }\\n }\\n\\n function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\\n return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\\n }\\n\\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, a)\\n mstore(0x20, b)\\n value := keccak256(0x00, 0x40)\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/SoloNetPKP.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { PubkeyRouter } from \\\"./PubkeyRouter.sol\\\";\\nimport { PKPPermissions } from \\\"./PKPPermissions.sol\\\";\\nimport { PKPNFTMetadata } from \\\"./PKPNFTMetadata.sol\\\";\\nimport { ERC721Burnable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol\\\";\\nimport { ERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport { IERC721Metadata } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { Staking } from \\\"./Staking.sol\\\";\\nimport \\\"solidity-bytes-utils/contracts/BytesLib.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n// TODO: tests for the mintGrantAndBurn function, withdraw function, some of the setters, transfer function, freeMint and freeMintGrantAndBurn\\n\\n/// @title Programmable Keypair NFT\\n///\\n/// @dev This is the contract for the PKP NFTs\\n///\\n/// Simply put, whomever owns a PKP NFT can ask that PKP to sign a message.\\n/// The owner can also grant signing permissions to other eth addresses\\n/// or lit actions\\ncontract SoloNetPKP is\\n ERC721(\\\"Programmable Keypair\\\", \\\"PKP\\\"),\\n Ownable,\\n ERC721Burnable,\\n ERC721Enumerable,\\n ReentrancyGuard\\n{\\n using BytesLib for bytes;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n PKPPermissions public pkpPermissions;\\n PKPNFTMetadata public pkpNftMetadata;\\n uint256 public mintCost;\\n address public freeMintSigner;\\n Staking public staking;\\n EnumerableSet.AddressSet permittedMinters;\\n\\n // map tokenId to the actual pubkey\\n mapping(uint256 => bytes) public pubkeys;\\n\\n // map the eth address to a pkp id\\n mapping(address => uint256) public ethAddressToPkpId;\\n\\n mapping(uint256 => bool) public redeemedFreeMintIds;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor() {\\n mintCost = 1e14; // 0.0001 eth\\n freeMintSigner = msg.sender;\\n permittedMinters.add(msg.sender);\\n }\\n\\n /* ========== VIEWS ========== */\\n\\n /// get the eth address for the keypair\\n function getEthAddress(uint256 tokenId) public view returns (address) {\\n // remove 0x04 prefix\\n bytes memory pubkey = pubkeys[tokenId].slice(1, 64);\\n bytes32 hashed = keccak256(pubkey);\\n return address(uint160(uint256(hashed)));\\n }\\n\\n /// includes the 0x04 prefix so you can pass this directly to ethers.utils.computeAddress\\n function getPubkey(uint256 tokenId) public view returns (bytes memory) {\\n return pubkeys[tokenId];\\n }\\n\\n /// throws if the sig is bad or msg doesn't match\\n function freeMintSigTest(\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public view {\\n bytes32 expectedHash = prefixed(\\n keccak256(abi.encodePacked(address(this), freeMintId))\\n );\\n require(\\n expectedHash == msgHash,\\n \\\"The msgHash is not a hash of the tokenId. Explain yourself!\\\"\\n );\\n\\n // make sure it was actually signed by freeMintSigner\\n address recovered = ecrecover(msgHash, v, r, s);\\n require(\\n recovered == freeMintSigner,\\n \\\"This freeMint was not signed by freeMintSigner. How embarassing.\\\"\\n );\\n\\n // prevent reuse\\n require(\\n redeemedFreeMintIds[freeMintId] == false,\\n \\\"This free mint ID has already been redeemed\\\"\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {\\n return\\n interfaceId == type(IERC721Enumerable).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n interfaceId == type(IERC721).interfaceId;\\n }\\n\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override(ERC721, ERC721Enumerable) {\\n ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);\\n }\\n\\n function tokenURI(\\n uint256 tokenId\\n ) public view override returns (string memory) {\\n console.log(\\\"getting token uri\\\");\\n bytes memory pubKey = getPubkey(tokenId);\\n console.log(\\\"got pubkey, getting eth address\\\");\\n address ethAddress = getEthAddress(tokenId);\\n console.log(\\\"calling tokenURI\\\");\\n\\n return pkpNftMetadata.tokenURI(tokenId, pubKey, ethAddress);\\n }\\n\\n // Builds a prefixed hash to mimic the behavior of eth_sign.\\n function prefixed(bytes32 hash) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n );\\n }\\n\\n function exists(uint256 tokenId) public view returns (bool) {\\n return _exists(tokenId);\\n }\\n\\n function _getTokenIdToMint(\\n bytes memory pubkey\\n ) public view returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n return tokenId;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n function mint(bytes memory pubkey) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _getTokenIdToMint(pubkey);\\n\\n _mintWithoutValueCheck(pubkey, msg.sender);\\n return tokenId;\\n }\\n\\n function mintGrantAndBurn(\\n bytes memory pubkey,\\n bytes memory ipfsCID\\n ) public payable returns (uint256) {\\n require(msg.value == mintCost, \\\"You must pay exactly mint cost\\\");\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function freeMint(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, msg.sender);\\n redeemedFreeMintIds[freeMintId] = true;\\n return tokenId;\\n }\\n\\n function freeMintGrantAndBurn(\\n bytes memory pubkey,\\n uint256 freeMintId,\\n bytes memory ipfsCID,\\n bytes32 msgHash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public returns (uint256) {\\n require(\\n permittedMinters.contains(tx.origin),\\n \\\"You are not permitted to mint\\\"\\n );\\n\\n // this will panic if the sig is bad\\n freeMintSigTest(freeMintId, msgHash, v, r, s);\\n uint256 tokenId = _mintWithoutValueCheck(pubkey, address(this));\\n redeemedFreeMintIds[freeMintId] = true;\\n pkpPermissions.addPermittedAction(tokenId, ipfsCID, new uint256[](0));\\n _burn(tokenId);\\n return tokenId;\\n }\\n\\n function _mintWithoutValueCheck(\\n bytes memory pubkey,\\n address to\\n ) internal returns (uint256) {\\n uint256 tokenId = uint256(keccak256(pubkey));\\n require(pubkeys[tokenId].length == 0, \\\"This pubkey already exists\\\");\\n pubkeys[tokenId] = pubkey;\\n\\n address pkpAddress = getEthAddress(tokenId);\\n ethAddressToPkpId[pkpAddress] = tokenId;\\n\\n if (to == address(this)) {\\n // permit unsafe transfer only to this contract, because it's going to be burned\\n _mint(to, tokenId);\\n } else {\\n _safeMint(to, tokenId);\\n }\\n\\n return tokenId;\\n }\\n\\n function setStakingAddress(address stakingAddress) public onlyOwner {\\n staking = Staking(stakingAddress);\\n emit StakingAddressSet(stakingAddress);\\n }\\n\\n function addPermittedMinter(address newPermittedMinter) public onlyOwner {\\n permittedMinters.add(newPermittedMinter);\\n emit MinterPermitted(newPermittedMinter);\\n }\\n\\n function removePermittedMinter(\\n address newPermittedMinter\\n ) public onlyOwner {\\n permittedMinters.remove(newPermittedMinter);\\n emit MinterRevoked(newPermittedMinter);\\n }\\n\\n function setPkpNftMetadataAddress(\\n address pkpNftMetadataAddress\\n ) public onlyOwner {\\n pkpNftMetadata = PKPNFTMetadata(pkpNftMetadataAddress);\\n emit PkpNftMetadataAddressSet(pkpNftMetadataAddress);\\n }\\n\\n function setPkpPermissionsAddress(\\n address pkpPermissionsAddress\\n ) public onlyOwner {\\n pkpPermissions = PKPPermissions(pkpPermissionsAddress);\\n emit PkpPermissionsAddressSet(pkpPermissionsAddress);\\n }\\n\\n function setMintCost(uint256 newMintCost) public onlyOwner {\\n mintCost = newMintCost;\\n emit MintCostSet(newMintCost);\\n }\\n\\n function setFreeMintSigner(address newFreeMintSigner) public onlyOwner {\\n freeMintSigner = newFreeMintSigner;\\n emit FreeMintSignerSet(newFreeMintSigner);\\n }\\n\\n function withdraw() public onlyOwner nonReentrant {\\n uint256 withdrawAmount = address(this).balance;\\n (bool sent, ) = payable(msg.sender).call{ value: withdrawAmount }(\\\"\\\");\\n require(sent);\\n emit Withdrew(withdrawAmount);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event StakingAddressSet(address indexed stakingAddress);\\n event PkpNftMetadataAddressSet(address indexed pkpNftMetadataAddress);\\n event PkpPermissionsAddressSet(address indexed pkpPermissionsAddress);\\n event MintCostSet(uint256 newMintCost);\\n event FreeMintSignerSet(address indexed newFreeMintSigner);\\n event Withdrew(uint256 amount);\\n event PkpRouted(uint256 indexed tokenId, uint256 indexed keyType);\\n event MinterPermitted(address indexed minter);\\n event MinterRevoked(address indexed minter);\\n}\\n\",\"versionPragma\":\"^0.8.17\"}}}","address":"0x3caabF13e5B19fB60a36ba4810fe2d6a9FA40bdF","bytecode":"0x60806040523480156200001157600080fd5b506040516200254d3803806200254d833981810160405281019062000037919062000217565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200025e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001df82620001b2565b9050919050565b620001f181620001d2565b8114620001fd57600080fd5b50565b6000815190506200021181620001e6565b92915050565b60008060408385031215620002315762000230620001ad565b5b6000620002418582860162000200565b9250506020620002548582860162000200565b9150509250929050565b6122df806200026e6000396000f3fe6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220d61d50d761857728b0369a97ebdf4d0de6a091f940988a32c49e94b239abc78464736f6c63430008110033","deployedBytecode":"0x6080604052600436106100915760003560e01c8063715018a611610059578063715018a6146101855780638da5cb5b1461019c57806397016f3f146101c7578063f2fde38b146101f2578063ffa2e9531461021b57610091565b8063150b7a0214610096578063176354fd146100d35780631ea89a22146100fc578063208f08c41461012557806358176bce14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190611011565b610246565b6040516100ca91906110d4565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f591906110ef565b6102eb565b005b34801561010857600080fd5b50610123600480360381019061011e91906110ef565b610337565b005b61013f600480360381019061013a91906115dd565b610383565b60405161014c91906117dc565b60405180910390f35b61016f600480360381019061016a91906117f7565b610b59565b60405161017c91906117dc565b60405180910390f35b34801561019157600080fd5b5061019a610cae565b005b3480156101a857600080fd5b506101b1610cc2565b6040516101be9190611934565b60405180910390f35b3480156101d357600080fd5b506101dc610ceb565b6040516101e991906119ae565b60405180910390f35b3480156101fe57600080fd5b50610219600480360381019061021491906110ef565b610d11565b005b34801561022757600080fd5b50610230610d94565b60405161023d91906119ea565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102cf90611a88565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6102f3610dba565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61033f610dba565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ba0e2e7348f6040518363ffffffff1660e01b81526004016103e29190611b27565b60206040518083038185885af1158015610400573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104259190611b5e565b90508a518c511461046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290611bfd565b60405180910390fd5b88518a51146104af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a690611c8f565b60405180910390fd5b86518851146104f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ea90611d21565b60405180910390fd5b8551885114610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e90611db3565b60405180910390fd5b845188511461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057290611e45565b60405180910390fd5b60008c511461066a5760005b8c5181101561066857600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638a431578838f84815181106105e2576105e1611e65565b5b60200260200101518f85815181106105fd576105fc611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161062393929190611f52565b600060405180830381600087803b15801561063d57600080fd5b505af1158015610651573d6000803e3d6000fd5b50505050808061066090611fc6565b915050610587565b505b60008a51146107595760005b8a5181101561075757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c121838d84815181106106d1576106d0611e65565b5b60200260200101518d85815181106106ec576106eb611e65565b5b60200260200101516040518463ffffffff1660e01b81526004016107129392919061200e565b600060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b50505050808061074f90611fc6565b915050610676565b505b60008851146108965760005b885181101561089457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dd4349b8360405180606001604052808d86815181106107cb576107ca611e65565b5b602002602001015181526020018c86815181106107eb576107ea611e65565b5b602002602001015181526020018b868151811061080b5761080a611e65565b5b602002602001015181525089858151811061082957610828611e65565b5b60200260200101516040518463ffffffff1660e01b815260040161084f939291906120ed565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050808061088c90611fc6565b915050610765565b505b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd4986a0836040518263ffffffff1660e01b81526004016108f391906117dc565b602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612147565b90508415610a1757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631663c1218383600067ffffffffffffffff81111561099757610996611132565b5b6040519080825280602002602001820160405280156109c55781602001602082028036833780820191505090505b506040518463ffffffff1660e01b81526004016109e49392919061200e565b600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b505050505b8315610ab357600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b8152600401610a7c93929190612174565b600060405180830381600087803b158015610a9657600080fd5b505af1158015610aaa573d6000803e3d6000fd5b50505050610b45565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033856040518463ffffffff1660e01b8152600401610b1293929190612174565b600060405180830381600087803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b505050505b81925050509b9a5050505050505050505050565b6000610ca188600067ffffffffffffffff811115610b7a57610b79611132565b5b604051908082528060200260200182016040528015610bad57816020015b6060815260200190600190039081610b985790505b50600067ffffffffffffffff811115610bc957610bc8611132565b5b604051908082528060200260200182016040528015610bfc57816020015b6060815260200190600190039081610be75790505b50600067ffffffffffffffff811115610c1857610c17611132565b5b604051908082528060200260200182016040528015610c465781602001602082028036833780820191505090505b50600067ffffffffffffffff811115610c6257610c61611132565b5b604051908082528060200260200182016040528015610c9557816020015b6060815260200190600190039081610c805790505b508c8c8c8c8c8c610383565b9050979650505050505050565b610cb6610dba565b610cc06000610e38565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d19610dba565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f9061221d565b60405180910390fd5b610d9181610e38565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610dc2610efc565b73ffffffffffffffffffffffffffffffffffffffff16610de0610cc2565b73ffffffffffffffffffffffffffffffffffffffff1614610e36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2d90612289565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f4382610f18565b9050919050565b610f5381610f38565b8114610f5e57600080fd5b50565b600081359050610f7081610f4a565b92915050565b6000819050919050565b610f8981610f76565b8114610f9457600080fd5b50565b600081359050610fa681610f80565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610fd157610fd0610fac565b5b8235905067ffffffffffffffff811115610fee57610fed610fb1565b5b60208301915083600182028301111561100a57611009610fb6565b5b9250929050565b60008060008060006080868803121561102d5761102c610f0e565b5b600061103b88828901610f61565b955050602061104c88828901610f61565b945050604061105d88828901610f97565b935050606086013567ffffffffffffffff81111561107e5761107d610f13565b5b61108a88828901610fbb565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6110ce81611099565b82525050565b60006020820190506110e960008301846110c5565b92915050565b60006020828403121561110557611104610f0e565b5b600061111384828501610f61565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61116a82611121565b810181811067ffffffffffffffff8211171561118957611188611132565b5b80604052505050565b600061119c610f04565b90506111a88282611161565b919050565b600067ffffffffffffffff8211156111c8576111c7611132565b5b6111d182611121565b9050602081019050919050565b82818337600083830152505050565b60006112006111fb846111ad565b611192565b90508281526020810184848401111561121c5761121b61111c565b5b6112278482856111de565b509392505050565b600082601f83011261124457611243610fac565b5b81356112548482602086016111ed565b91505092915050565b600067ffffffffffffffff82111561127857611277611132565b5b602082029050602081019050919050565b600061129c6112978461125d565b611192565b905080838252602082019050602084028301858111156112bf576112be610fb6565b5b835b8181101561130657803567ffffffffffffffff8111156112e4576112e3610fac565b5b8086016112f1898261122f565b855260208501945050506020810190506112c1565b5050509392505050565b600082601f83011261132557611324610fac565b5b8135611335848260208601611289565b91505092915050565b600067ffffffffffffffff82111561135957611358611132565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561138557611384611132565b5b602082029050602081019050919050565b60006113a96113a48461136a565b611192565b905080838252602082019050602084028301858111156113cc576113cb610fb6565b5b835b818110156113f557806113e18882610f97565b8452602084019350506020810190506113ce565b5050509392505050565b600082601f83011261141457611413610fac565b5b8135611424848260208601611396565b91505092915050565b600061144061143b8461133e565b611192565b9050808382526020820190506020840283018581111561146357611462610fb6565b5b835b818110156114aa57803567ffffffffffffffff81111561148857611487610fac565b5b80860161149589826113ff565b85526020850194505050602081019050611465565b5050509392505050565b600082601f8301126114c9576114c8610fac565b5b81356114d984826020860161142d565b91505092915050565b600067ffffffffffffffff8211156114fd576114fc611132565b5b602082029050602081019050919050565b600061152161151c846114e2565b611192565b9050808382526020820190506020840283018581111561154457611543610fb6565b5b835b8181101561156d57806115598882610f61565b845260208401935050602081019050611546565b5050509392505050565b600082601f83011261158c5761158b610fac565b5b813561159c84826020860161150e565b91505092915050565b60008115159050919050565b6115ba816115a5565b81146115c557600080fd5b50565b6000813590506115d7816115b1565b92915050565b60008060008060008060008060008060006101608c8e03121561160357611602610f0e565b5b60008c013567ffffffffffffffff81111561162157611620610f13565b5b61162d8e828f0161122f565b9b505060208c013567ffffffffffffffff81111561164e5761164d610f13565b5b61165a8e828f01611310565b9a505060408c013567ffffffffffffffff81111561167b5761167a610f13565b5b6116878e828f016114b4565b99505060608c013567ffffffffffffffff8111156116a8576116a7610f13565b5b6116b48e828f01611577565b98505060808c013567ffffffffffffffff8111156116d5576116d4610f13565b5b6116e18e828f016114b4565b97505060a08c013567ffffffffffffffff81111561170257611701610f13565b5b61170e8e828f016113ff565b96505060c08c013567ffffffffffffffff81111561172f5761172e610f13565b5b61173b8e828f01611310565b95505060e08c013567ffffffffffffffff81111561175c5761175b610f13565b5b6117688e828f01611310565b9450506101008c013567ffffffffffffffff81111561178a57611789610f13565b5b6117968e828f016114b4565b9350506101206117a88e828f016115c8565b9250506101406117ba8e828f016115c8565b9150509295989b509295989b9093969950565b6117d681610f76565b82525050565b60006020820190506117f160008301846117cd565b92915050565b600080600080600080600060e0888a03121561181657611815610f0e565b5b600088013567ffffffffffffffff81111561183457611833610f13565b5b6118408a828b0161122f565b975050602088013567ffffffffffffffff81111561186157611860610f13565b5b61186d8a828b016113ff565b965050604088013567ffffffffffffffff81111561188e5761188d610f13565b5b61189a8a828b01611310565b955050606088013567ffffffffffffffff8111156118bb576118ba610f13565b5b6118c78a828b01611310565b945050608088013567ffffffffffffffff8111156118e8576118e7610f13565b5b6118f48a828b016114b4565b93505060a06119058a828b016115c8565b92505060c06119168a828b016115c8565b91505092959891949750929550565b61192e81610f38565b82525050565b60006020820190506119496000830184611925565b92915050565b6000819050919050565b600061197461196f61196a84610f18565b61194f565b610f18565b9050919050565b600061198682611959565b9050919050565b60006119988261197b565b9050919050565b6119a88161198d565b82525050565b60006020820190506119c3600083018461199f565b92915050565b60006119d48261197b565b9050919050565b6119e4816119c9565b82525050565b60006020820190506119ff60008301846119db565b92915050565b600082825260208201905092915050565b7f504b5048656c7065723a206f6e6c792061636365707473207472616e7366657260008201527f732066726f6d2074686520504b504e465420636f6e7472616374000000000000602082015250565b6000611a72603a83611a05565b9150611a7d82611a16565b604082019050919050565b60006020820190508181036000830152611aa181611a65565b9050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ae2578082015181840152602081019050611ac7565b60008484015250505050565b6000611af982611aa8565b611b038185611ab3565b9350611b13818560208601611ac4565b611b1c81611121565b840191505092915050565b60006020820190508181036000830152611b418184611aee565b905092915050565b600081519050611b5881610f80565b92915050565b600060208284031215611b7457611b73610f0e565b5b6000611b8284828501611b49565b91505092915050565b7f504b5048656c7065723a20697066732063696420616e642073636f706520617260008201527f726179206c656e67746873206d757374206d6174636800000000000000000000602082015250565b6000611be7603683611a05565b9150611bf282611b8b565b604082019050919050565b60006020820190508181036000830152611c1681611bda565b9050919050565b7f504b5048656c7065723a206164647265737320616e642073636f70652061727260008201527f6179206c656e67746873206d757374206d617463680000000000000000000000602082015250565b6000611c79603583611a05565b9150611c8482611c1d565b604082019050919050565b60006020820190508181036000830152611ca881611c6c565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f6964206172726179206c656e67746873206d757374206d617463680000000000602082015250565b6000611d0b603b83611a05565b9150611d1682611caf565b604082019050919050565b60006020820190508181036000830152611d3a81611cfe565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f7075626b6579206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611d9d603f83611a05565b9150611da882611d41565b604082019050919050565b60006020820190508181036000830152611dcc81611d90565b9050919050565b7f504b5048656c7065723a2061757468206d6574686f64207479706520616e642060008201527f73636f706573206172726179206c656e67746873206d757374206d6174636800602082015250565b6000611e2f603f83611a05565b9150611e3a82611dd3565b604082019050919050565b60006020820190508181036000830152611e5e81611e22565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611ec981610f76565b82525050565b6000611edb8383611ec0565b60208301905092915050565b6000602082019050919050565b6000611eff82611e94565b611f098185611e9f565b9350611f1483611eb0565b8060005b83811015611f45578151611f2c8882611ecf565b9750611f3783611ee7565b925050600181019050611f18565b5085935050505092915050565b6000606082019050611f6760008301866117cd565b8181036020830152611f798185611aee565b90508181036040830152611f8d8184611ef4565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd182610f76565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200357612002611f97565b5b600182019050919050565b600060608201905061202360008301866117cd565b6120306020830185611925565b81810360408301526120428184611ef4565b9050949350505050565b600082825260208201905092915050565b600061206882611aa8565b612072818561204c565b9350612082818560208601611ac4565b61208b81611121565b840191505092915050565b60006060830160008301516120ae6000860182611ec0565b50602083015184820360208601526120c6828261205d565b915050604083015184820360408601526120e0828261205d565b9150508091505092915050565b600060608201905061210260008301866117cd565b81810360208301526121148185612096565b905081810360408301526121288184611ef4565b9050949350505050565b60008151905061214181610f4a565b92915050565b60006020828403121561215d5761215c610f0e565b5b600061216b84828501612132565b91505092915050565b60006060820190506121896000830186611925565b6121966020830185611925565b6121a360408301846117cd565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612207602683611a05565b9150612212826121ab565b604082019050919050565b60006020820190508181036000830152612236816121fa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612273602083611a05565b915061227e8261223d565b602082019050919050565b600060208201905081810360008301526122a281612266565b905091905056fea2646970667358221220d61d50d761857728b0369a97ebdf4d0de6a091f940988a32c49e94b239abc78464736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_pkpNft","type":"address"},{"internalType":"address","name":"_pkpPermissions","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":"bytes","name":"pubkey","type":"bytes"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes[]","name":"permittedIpfsCIDs","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedIpfsCIDScopes","type":"uint256[][]"},{"internalType":"address[]","name":"permittedAddresses","type":"address[]"},{"internalType":"uint256[][]","name":"permittedAddressScopes","type":"uint256[][]"},{"internalType":"uint256[]","name":"permittedAuthMethodTypes","type":"uint256[]"},{"internalType":"bytes[]","name":"permittedAuthMethodIds","type":"bytes[]"},{"internalType":"bytes[]","name":"permittedAuthMethodPubkeys","type":"bytes[]"},{"internalType":"uint256[][]","name":"permittedAuthMethodScopes","type":"uint256[][]"},{"internalType":"bool","name":"addPkpEthAddressAsPermittedAddress","type":"bool"},{"internalType":"bool","name":"sendPkpToItself","type":"bool"}],"name":"mintAndAddAuthMethodsWithTypes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpNFT","outputs":[{"internalType":"contract SoloNetPKP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pkpPermissions","outputs":[{"internalType":"contract PKPPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpNftAddress","type":"address"}],"name":"setPkpNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPkpPermissionsAddress","type":"address"}],"name":"setPkpPermissionsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/deployments/rolluptestnet_987/Staking.json b/deployments/rolluptestnet_987/Staking.json deleted file mode 100644 index 18a288e..0000000 --- a/deployments/rolluptestnet_987/Staking.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":"{\"defaultCompiler\":{\"version\":\"0.8.17\"},\"sources\":{\"contracts/Staking.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { EnumerableSet } from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport { LITToken } from \\\"./LITToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract Staking is ReentrancyGuard, Pausable, Ownable {\\n using SafeERC20 for LITToken;\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /* ========== STATE VARIABLES ========== */\\n\\n enum States {\\n Active,\\n NextValidatorSetLocked,\\n ReadyForNextEpoch,\\n Unlocked,\\n Paused\\n }\\n\\n // this enum is not used, and instead we use an integer so that\\n // we can add more reasons after the contract is deployed.\\n // This enum is kept in the comments here for reference.\\n // enum KickReason {\\n // NULLREASON, // 0\\n // UNRESPONSIVE, // 1\\n // BAD_ATTESTATION // 2\\n // }\\n\\n States public state = States.Active;\\n\\n LITToken public stakingToken;\\n\\n struct Epoch {\\n uint256 epochLength;\\n uint256 number;\\n uint256 endBlock; //\\n uint256 retries; // incremented upon failure to advance and subsequent unlock\\n uint256 timeout; // timeout in blocks, where the nodes can be unlocked.\\n }\\n\\n Epoch public epoch;\\n\\n uint256 public tokenRewardPerTokenPerEpoch;\\n\\n uint256 public minimumStake;\\n uint256 public totalStaked;\\n\\n // tokens slashed when kicked\\n uint256 public kickPenaltyPercent;\\n\\n EnumerableSet.AddressSet validatorsInCurrentEpoch;\\n EnumerableSet.AddressSet validatorsInNextEpoch;\\n EnumerableSet.AddressSet validatorsKickedFromNextEpoch;\\n\\n struct Validator {\\n uint32 ip;\\n uint128 ipv6;\\n uint32 port;\\n address nodeAddress;\\n uint256 balance;\\n uint256 reward;\\n uint256 senderPubKey;\\n uint256 receiverPubKey;\\n }\\n\\n struct VoteToKickValidatorInNextEpoch {\\n uint256 votes;\\n mapping(address => bool) voted;\\n }\\n\\n // list of all validators, even ones that are not in the current or next epoch\\n // maps STAKER address to Validator struct\\n mapping(address => Validator) public validators;\\n\\n // stakers join by staking, but nodes need to be able to vote to kick.\\n // to avoid node operators having to run a hotwallet with their staking private key,\\n // the node gets it's own private key that it can use to vote to kick,\\n // or signal that the next epoch is ready.\\n // this mapping lets you go from the nodeAddressto the stakingAddress.\\n mapping(address => address) public nodeAddressToStakerAddress;\\n\\n // after the validator set is locked, nodes vote that they have successfully completed the PSS\\n // operation. Once a threshold of nodes have voted that they are ready, then the epoch can advance\\n mapping(address => bool) public readyForNextEpoch;\\n\\n // nodes can vote to kick another node. If a threshold of nodes vote to kick someone, they\\n // are removed from the next validator set\\n mapping(uint256 => mapping(address => VoteToKickValidatorInNextEpoch))\\n public votesToKickValidatorsInNextEpoch;\\n\\n // resolver contract address. the resolver contract is used to lookup other contract addresses.\\n address public resolverContractAddress;\\n\\n /* ========== CONSTRUCTOR ========== */\\n constructor(address _stakingToken) {\\n stakingToken = LITToken(_stakingToken);\\n epoch = Epoch({\\n epochLength: 80,\\n number: 1,\\n endBlock: block.number + 1,\\n retries: 0,\\n timeout: 80\\n });\\n // 0.05 tokens per token staked meaning a 5% per epoch inflation rate\\n tokenRewardPerTokenPerEpoch = (10 ** stakingToken.decimals()) / 20;\\n // 1 token minimum stake\\n minimumStake = 1 * (10 ** stakingToken.decimals());\\n kickPenaltyPercent = 5;\\n }\\n\\n /* ========== VIEWS ========== */\\n function isActiveValidator(address account) external view returns (bool) {\\n return validatorsInCurrentEpoch.contains(account);\\n }\\n\\n function rewardOf(address account) external view returns (uint256) {\\n return validators[account].reward;\\n }\\n\\n function balanceOf(address account) external view returns (uint256) {\\n return validators[account].balance;\\n }\\n\\n function getVotingStatusToKickValidator(\\n uint256 epochNumber,\\n address validatorStakerAddress,\\n address voterStakerAddress\\n ) external view returns (uint256, bool) {\\n VoteToKickValidatorInNextEpoch\\n storage votingStatus = votesToKickValidatorsInNextEpoch[\\n epochNumber\\n ][validatorStakerAddress];\\n return (votingStatus.votes, votingStatus.voted[voterStakerAddress]);\\n }\\n\\n function getValidatorsInCurrentEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](\\n validatorsInCurrentEpoch.length()\\n );\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInCurrentEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function getValidatorsInNextEpoch()\\n external\\n view\\n returns (address[] memory)\\n {\\n address[] memory values = new address[](validatorsInNextEpoch.length());\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n values[i] = validatorsInNextEpoch.at(i);\\n }\\n return values;\\n }\\n\\n function isReadyForNextEpoch() public view returns (bool) {\\n uint256 total = 0;\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n if (readyForNextEpoch[validatorsInNextEpoch.at(i)]) {\\n total++;\\n }\\n }\\n if ((total >= validatorCountForConsensus())) {\\n // 2/3 of validators must be ready\\n return true;\\n }\\n return false;\\n }\\n\\n function shouldKickValidator(\\n address stakerAddress\\n ) public view returns (bool) {\\n VoteToKickValidatorInNextEpoch\\n storage vk = votesToKickValidatorsInNextEpoch[epoch.number][\\n stakerAddress\\n ];\\n if (vk.votes >= validatorCountForConsensus()) {\\n // 2/3 of validators must vote\\n return true;\\n }\\n return false;\\n }\\n\\n // these could be checked with uint return value with the state getter, but included defensively in case more states are added.\\n function validatorsInNextEpochAreLocked() public view returns (bool) {\\n return state == States.NextValidatorSetLocked;\\n }\\n\\n function validatorStateIsActive() public view returns (bool) {\\n return state == States.Active;\\n }\\n\\n function validatorStateIsUnlocked() public view returns (bool) {\\n return state == States.Unlocked;\\n }\\n\\n // currently set to 2/3. this could be changed to be configurable.\\n function validatorCountForConsensus() public view returns (uint256) {\\n if (validatorsInCurrentEpoch.length() <= 2) {\\n return 1;\\n }\\n return (validatorsInCurrentEpoch.length() * 2) / 3;\\n }\\n\\n /* ========== MUTATIVE FUNCTIONS ========== */\\n\\n /// Lock in the validators for the next epoch\\n function lockValidatorsForNextEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.Active || state == States.Unlocked,\\n \\\"Must be in active or unlocked state\\\"\\n );\\n\\n state = States.NextValidatorSetLocked;\\n emit StateChanged(state);\\n }\\n\\n /// After proactive secret sharing is complete, the nodes may signal that they are ready for the next epoch. Note that this function is called by the node itself, and so msg.sender is the nodeAddress and not the stakerAddress.\\n function signalReadyForNextEpoch() public {\\n address stakerAddress = nodeAddressToStakerAddress[msg.sender];\\n require(\\n state == States.NextValidatorSetLocked ||\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in state NextValidatorSetLocked or ReadyForNextEpoch\\\"\\n );\\n // at the first epoch, validatorsInCurrentEpoch is empty\\n if (epoch.number != 1) {\\n require(\\n validatorsInNextEpoch.contains(stakerAddress),\\n \\\"Validator is not in the next epoch\\\"\\n );\\n }\\n readyForNextEpoch[stakerAddress] = true;\\n emit ReadyForNextEpoch(stakerAddress);\\n\\n if (isReadyForNextEpoch()) {\\n state = States.ReadyForNextEpoch;\\n emit StateChanged(state);\\n }\\n }\\n\\n /// If the nodes fail to advance (e.g. because dkg failed), anyone can call to unlock and allow retry\\n function unlockValidatorsForNextEpoch() public {\\n // the deadline to advance is thus epoch.endBlock + epoch.timeout\\n require(\\n block.number >= epoch.endBlock + epoch.timeout,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.NextValidatorSetLocked,\\n \\\"Must be in NextValidatorSetLocked\\\"\\n );\\n\\n uint256 validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.retries++;\\n\\n state = States.Unlocked;\\n emit StateChanged(state);\\n }\\n\\n /// Advance to the next Epoch. Rewards validators, adds the joiners, and removes the leavers\\n function advanceEpoch() public {\\n require(\\n block.number >= epoch.endBlock,\\n \\\"Enough blocks have not elapsed since the last epoch\\\"\\n );\\n require(\\n state == States.ReadyForNextEpoch,\\n \\\"Must be in ready for next epoch state\\\"\\n );\\n require(\\n isReadyForNextEpoch() == true,\\n \\\"Not enough validators are ready for the next epoch\\\"\\n );\\n\\n // reward the validators\\n uint256 validatorLength = validatorsInCurrentEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n address validatorAddress = validatorsInCurrentEpoch.at(i);\\n validators[validatorAddress].reward +=\\n (tokenRewardPerTokenPerEpoch *\\n validators[validatorAddress].balance) /\\n 10 ** stakingToken.decimals();\\n }\\n\\n // set the validators to the new validator set\\n // ideally we could just do this:\\n // validatorsInCurrentEpoch = validatorsInNextEpoch;\\n // but solidity doesn't allow that, so we have to do it manually\\n\\n // clear out validators in current epoch\\n while (validatorsInCurrentEpoch.length() > 0) {\\n validatorsInCurrentEpoch.remove(validatorsInCurrentEpoch.at(0));\\n }\\n\\n // copy validators from next epoch to current epoch\\n validatorLength = validatorsInNextEpoch.length();\\n for (uint256 i = 0; i < validatorLength; i++) {\\n validatorsInCurrentEpoch.add(validatorsInNextEpoch.at(i));\\n\\n // clear out readyForNextEpoch\\n readyForNextEpoch[validatorsInNextEpoch.at(i)] = false;\\n }\\n\\n epoch.number++;\\n epoch.endBlock = block.number + epoch.epochLength; // not epoch.endBlock +\\n\\n state = States.Active;\\n emit StateChanged(state);\\n }\\n\\n /// Stake and request to join the validator set\\n /// @param amount The amount of tokens to stake\\n /// @param ip The IP address of the node\\n /// @param port The port of the node\\n function stakeAndJoin(\\n uint256 amount,\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public whenNotPaused {\\n stake(amount);\\n requestToJoin(\\n ip,\\n ipv6,\\n port,\\n nodeAddress,\\n senderPubKey,\\n receiverPubKey\\n );\\n }\\n\\n /// Stake tokens for a validator\\n function stake(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot stake 0\\\");\\n\\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\\n validators[msg.sender].balance += amount;\\n\\n totalStaked += amount;\\n\\n emit Staked(msg.sender, amount);\\n }\\n\\n function requestToJoin(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public nonReentrant {\\n uint256 amountStaked = validators[msg.sender].balance;\\n require(\\n amountStaked >= minimumStake,\\n \\\"Stake must be greater than or equal to minimumStake\\\"\\n );\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to join\\\"\\n );\\n\\n // make sure they haven't been kicked\\n require(\\n validatorsKickedFromNextEpoch.contains(msg.sender) == false,\\n \\\"You cannot rejoin if you have been kicked until the next epoch\\\"\\n );\\n\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n nodeAddressToStakerAddress[nodeAddress] = msg.sender;\\n\\n validatorsInNextEpoch.add(msg.sender);\\n\\n emit RequestToJoin(msg.sender);\\n }\\n\\n /// Withdraw staked tokens. This can only be done by users who are not active in the validator set.\\n /// @param amount The amount of tokens to withdraw\\n function withdraw(uint256 amount) public nonReentrant {\\n require(amount > 0, \\\"Cannot withdraw 0\\\");\\n\\n require(\\n validatorsInCurrentEpoch.contains(msg.sender) == false,\\n \\\"Active validators cannot leave. Please use the leave() function and wait for the next epoch to leave\\\"\\n );\\n\\n require(\\n validators[msg.sender].balance >= amount,\\n \\\"Not enough tokens to withdraw\\\"\\n );\\n\\n totalStaked = totalStaked - amount;\\n validators[msg.sender].balance =\\n validators[msg.sender].balance -\\n amount;\\n stakingToken.safeTransfer(msg.sender, amount);\\n emit Withdrawn(msg.sender, amount);\\n }\\n\\n /// Request to leave in the next Epoch\\n function requestToLeave() public nonReentrant {\\n require(\\n state == States.Active ||\\n state == States.Unlocked ||\\n state == States.Paused,\\n \\\"Must be in Active or Unlocked state to request to leave\\\"\\n );\\n if (validatorsInNextEpoch.contains(msg.sender)) {\\n // remove them\\n validatorsInNextEpoch.remove(msg.sender);\\n }\\n emit RequestToLeave(msg.sender);\\n }\\n\\n /// Transfer any outstanding reward tokens\\n function getReward() public nonReentrant {\\n uint256 reward = validators[msg.sender].reward;\\n if (reward > 0) {\\n validators[msg.sender].reward = 0;\\n stakingToken.safeTransfer(msg.sender, reward);\\n emit RewardPaid(msg.sender, reward);\\n }\\n }\\n\\n /// Exit staking and get any outstanding rewards\\n function exit() public {\\n withdraw(validators[msg.sender].balance);\\n getReward();\\n }\\n\\n /// If more than the threshold of validators vote to kick someone, kick them.\\n /// It's expected that this will be called by the node directly, so msg.sender will be the nodeAddress\\n function kickValidatorInNextEpoch(\\n address validatorStakerAddress,\\n uint256 reason,\\n bytes calldata data\\n ) public nonReentrant {\\n address stakerAddressOfSender = nodeAddressToStakerAddress[msg.sender];\\n require(\\n stakerAddressOfSender != address(0),\\n \\\"Could not map your nodeAddress to your stakerAddress\\\"\\n );\\n require(\\n validatorsInNextEpoch.contains(stakerAddressOfSender),\\n \\\"You must be a validator in the next epoch to kick someone from the next epoch\\\"\\n );\\n require(\\n votesToKickValidatorsInNextEpoch[epoch.number][\\n validatorStakerAddress\\n ].voted[stakerAddressOfSender] == false,\\n \\\"You can only vote to kick someone once per epoch\\\"\\n );\\n\\n // Vote to kick\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .votes++;\\n votesToKickValidatorsInNextEpoch[epoch.number][validatorStakerAddress]\\n .voted[stakerAddressOfSender] = true;\\n\\n if (\\n validatorsInNextEpoch.contains(validatorStakerAddress) &&\\n shouldKickValidator(validatorStakerAddress)\\n ) {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n // slash the stake\\n uint256 amountToBurn = (validators[validatorStakerAddress].balance *\\n kickPenaltyPercent) / 100;\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n // shame them with an event\\n emit ValidatorKickedFromNextEpoch(\\n validatorStakerAddress,\\n amountToBurn\\n );\\n }\\n\\n emit VotedToKickValidatorInNextEpoch(\\n stakerAddressOfSender,\\n validatorStakerAddress,\\n reason,\\n data\\n );\\n }\\n\\n /// Set the IP and port of your node\\n /// @param ip The ip address of your node\\n /// @param port The port of your node\\n function setIpPortNodeAddressAndCommunicationPubKeys(\\n uint32 ip,\\n uint128 ipv6,\\n uint32 port,\\n address nodeAddress,\\n uint256 senderPubKey,\\n uint256 receiverPubKey\\n ) public {\\n validators[msg.sender].ip = ip;\\n validators[msg.sender].ipv6 = ipv6;\\n validators[msg.sender].port = port;\\n validators[msg.sender].nodeAddress = nodeAddress;\\n validators[msg.sender].senderPubKey = senderPubKey;\\n validators[msg.sender].receiverPubKey = receiverPubKey;\\n }\\n\\n function setEpochLength(uint256 newEpochLength) public onlyOwner {\\n epoch.epochLength = newEpochLength;\\n emit EpochLengthSet(newEpochLength);\\n }\\n\\n function setEpochTimeout(uint256 newEpochTimeout) public onlyOwner {\\n epoch.timeout = newEpochTimeout;\\n emit EpochTimeoutSet(newEpochTimeout);\\n }\\n\\n function setStakingToken(address newStakingTokenAddress) public onlyOwner {\\n stakingToken = LITToken(newStakingTokenAddress);\\n emit StakingTokenSet(newStakingTokenAddress);\\n }\\n\\n function setTokenRewardPerTokenPerEpoch(\\n uint256 newTokenRewardPerTokenPerEpoch\\n ) public onlyOwner {\\n tokenRewardPerTokenPerEpoch = newTokenRewardPerTokenPerEpoch;\\n emit TokenRewardPerTokenPerEpochSet(newTokenRewardPerTokenPerEpoch);\\n }\\n\\n function setMinimumStake(uint256 newMinimumStake) public onlyOwner {\\n minimumStake = newMinimumStake;\\n emit MinimumStakeSet(newMinimumStake);\\n }\\n\\n function setKickPenaltyPercent(\\n uint256 newKickPenaltyPercent\\n ) public onlyOwner {\\n kickPenaltyPercent = newKickPenaltyPercent;\\n emit KickPenaltyPercentSet(newKickPenaltyPercent);\\n }\\n\\n function setResolverContractAddress(\\n address newResolverContractAddress\\n ) public onlyOwner {\\n resolverContractAddress = newResolverContractAddress;\\n\\n emit ResolverContractAddressSet(newResolverContractAddress);\\n }\\n\\n function setEpochState(States newState) public onlyOwner {\\n state = newState;\\n emit StateChanged(newState);\\n }\\n\\n function pauseEpoch() public onlyOwner {\\n state = States.Paused;\\n emit StateChanged(States.Paused);\\n }\\n\\n function adminKickValidatorInNextEpoch(\\n address validatorStakerAddress\\n ) public nonReentrant onlyOwner {\\n // remove from next validator set\\n validatorsInNextEpoch.remove(validatorStakerAddress);\\n // block them from rejoining the next epoch\\n validatorsKickedFromNextEpoch.add(validatorStakerAddress);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, 0);\\n }\\n\\n function adminSlashValidator(\\n address validatorStakerAddress,\\n uint256 amountToBurn\\n ) public nonReentrant onlyOwner {\\n validators[validatorStakerAddress].balance -= amountToBurn;\\n totalStaked -= amountToBurn;\\n stakingToken.burn(amountToBurn);\\n emit ValidatorKickedFromNextEpoch(validatorStakerAddress, amountToBurn);\\n }\\n\\n /* ========== EVENTS ========== */\\n\\n event Staked(address indexed staker, uint256 amount);\\n event Withdrawn(address indexed staker, uint256 amount);\\n event RewardPaid(address indexed staker, uint256 reward);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event RequestToJoin(address indexed staker);\\n event RequestToLeave(address indexed staker);\\n event Recovered(address token, uint256 amount);\\n event ReadyForNextEpoch(address indexed staker);\\n event StateChanged(States newState);\\n event VotedToKickValidatorInNextEpoch(\\n address indexed reporter,\\n address indexed validatorStakerAddress,\\n uint256 indexed reason,\\n bytes data\\n );\\n event ValidatorKickedFromNextEpoch(\\n address indexed staker,\\n uint256 amountBurned\\n );\\n\\n // onlyOwner events\\n event EpochLengthSet(uint256 newEpochLength);\\n event EpochTimeoutSet(uint256 newEpochTimeout);\\n event StakingTokenSet(address newStakingTokenAddress);\\n event TokenRewardPerTokenPerEpochSet(\\n uint256 newTokenRewardPerTokenPerEpoch\\n );\\n event MinimumStakeSet(uint256 newMinimumStake);\\n event KickPenaltyPercentSet(uint256 newKickPenaltyPercent);\\n event ResolverContractAddressSet(address newResolverContractAddress);\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_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 // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\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 if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\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] = _HEX_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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\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 * ```\\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.\\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(uint160(account), 20),\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\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 * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\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 value {ERC20} uses, unless this function is\\n * 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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 }\\n _balances[to] += amount;\\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 _balances[account] += amount;\\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 }\\n _totalSupply -= amount;\\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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address owner,\\n address spender,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) 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(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"contracts/LITToken.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity ^0.8.17;\\n\\nimport { AccessControl } from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ERC20Burnable } from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/// @title Lit Protocol Token\\n///\\n/// @dev This is the contract for the Lit Protocol governance token.\\n///\\n/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,\\n/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,\\n/// the deployer must revoke their admin role and minter role.\\n///\\n/// This contract was initially borrowed from Alchemix, and modified extensively, from here: https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/AlchemixToken.sol\\ncontract LITToken is\\n AccessControl,\\n ERC20(\\\"Lit Protocol\\\", \\\"LIT\\\"),\\n ERC20Burnable\\n{\\n /// @dev The identifier of the role which maintains other roles.\\n bytes32 public constant ADMIN_ROLE = keccak256(\\\"ADMIN\\\");\\n\\n /// @dev The identifier of the role which allows accounts to mint tokens.\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER\\\");\\n\\n constructor() {\\n _setupRole(ADMIN_ROLE, msg.sender);\\n _setupRole(MINTER_ROLE, msg.sender);\\n _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);\\n _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\\n }\\n\\n /// @dev A modifier which checks that the caller has the minter role.\\n modifier onlyMinter() {\\n require(hasRole(MINTER_ROLE, msg.sender), \\\"LITToken: only minter\\\");\\n _;\\n }\\n\\n /// @dev Mints tokens to a recipient.\\n ///\\n /// This function reverts if the caller does not have the minter role.\\n ///\\n /// @param _recipient the account to mint tokens to.\\n /// @param _amount the amount of tokens to mint.\\n function mint(address _recipient, uint256 _amount) external onlyMinter {\\n _mint(_recipient, _amount);\\n }\\n}\\n\",\"versionPragma\":\"^0.8.17\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint256 p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint256 p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint256 p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint256 p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"versionPragma\":\">= 0.4.22 <0.9.0\"},\"@openzeppelin/contracts/security/Pausable.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/Context.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 Pausable is Context {\\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 constructor() {\\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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\\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 * ```\\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 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 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 return _values(set._inner);\\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 on 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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.1\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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\",\"versionPragma\":\"^0.8.0\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-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 function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) 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(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) 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 function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\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 if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"versionPragma\":\"^0.8.0\"}}}","address":"0x992FFBD717a9bf13e5aABDCb2E7e61064Ed68240","bytecode":"0x60806040526000600160156101000a81548160ff021916908360048111156200002d576200002c6200039f565b5b02179055503480156200003f57600080fd5b506040516200631238038062006312833981810160405281019062000065919062000438565b60016000819055506000600160006101000a81548160ff021916908315150217905550620000a86200009c620002d460201b60201c565b620002dc60201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060a001604052806050815260200160018152602001600143620001119190620004a3565b8152602001600081526020016050815250600360008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506014600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ef91906200051c565b600a620001fd9190620006a2565b62000209919062000722565b600881905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a391906200051c565b600a620002b19190620006a2565b6001620002bf91906200075a565b6009819055506005600b8190555050620007a5565b600033905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040082620003d3565b9050919050565b6200041281620003f3565b81146200041e57600080fd5b50565b600081519050620004328162000407565b92915050565b600060208284031215620004515762000450620003ce565b5b6000620004618482850162000421565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004b0826200046a565b9150620004bd836200046a565b9250828201905080821115620004d857620004d762000474565b5b92915050565b600060ff82169050919050565b620004f681620004de565b81146200050257600080fd5b50565b6000815190506200051681620004eb565b92915050565b600060208284031215620005355762000534620003ce565b5b6000620005458482850162000505565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115620005ad5780860481111562000585576200058462000474565b5b6001851615620005955780820291505b8081029050620005a5856200054e565b945062000565565b94509492505050565b600082620005c857600190506200069b565b81620005d857600090506200069b565b8160018114620005f15760028114620005fc5762000632565b60019150506200069b565b60ff84111562000611576200061062000474565b5b8360020a9150848211156200062b576200062a62000474565b5b506200069b565b5060208310610133831016604e8410600b84101617156200066c5782820a90508381111562000666576200066562000474565b5b6200069b565b6200067b84848460016200055b565b9250905081840481111562000695576200069462000474565b5b81810290505b9392505050565b6000620006af826200046a565b9150620006bc83620004de565b9250620006eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620005b6565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006200072f826200046a565b91506200073c836200046a565b9250826200074f576200074e620006f3565b5b828204905092915050565b600062000767826200046a565b915062000774836200046a565b925082820262000784816200046a565b915082820484148315176200079e576200079d62000474565b5b5092915050565b615b5d80620007b56000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea26469706673582212204882fa538c55ab56f1e64f81f9db5a68e93b40c4ee715f933a1609ca228180dd64736f6c63430008110033","deployedBytecode":"0x608060405234801561001057600080fd5b506004361061030c5760003560e01c8063857b76631161019d578063ba3bd22e116100e9578063e587b8a7116100a2578063f1887fec1161007c578063f1887fec14610872578063f2fde38b14610890578063f48d2a27146108ac578063fa52c7d8146108ca5761030c565b8063e587b8a71461082e578063e9fad8ee1461084a578063ec5ffac2146108545761030c565b8063ba3bd22e146107a4578063bee36e9c146107c0578063c006e00b146107ca578063c19d93fb146107d4578063c35d4d09146107f2578063dd21d626146108105761030c565b8063988ac27911610156578063ac2f8afe11610130578063ac2f8afe14610754578063b139603c1461075e578063b6688e0014610768578063b9ce6638146107865761030c565b8063988ac279146106fe578063a4c569b91461071a578063a694fc3a146107385761030c565b8063857b76631461064a578063865419e9146106685780638b80d833146106845780638d2b9c81146106a05780638da5cb5b146106be578063900cf0cf146106dc5761030c565b80634927a1431161025c57806370a082311161021557806372f702f3116101ef57806372f702f3146105c25780637aa086e7146105e0578063817b1cd2146105fc578063847e06251461061a5761030c565b806370a082311461055757806370fe276a14610587578063715018a6146105b85761030c565b80634927a143146104715780634f8f0102146104a15780635081f66f146104bd578063519877eb146104ed57806354eea7961461051d5780635c975abb146105395761030c565b80632e1a7d4d116102c95780633d18b912116102a35780633d18b912146103ff5780633f8197131461040957806340550a1c14610425578063455b0de6146104555761030c565b80632e1a7d4d146103bd5780633528db88146103d95780633cf80e6c146103f55761030c565b8063063d82391461031157806316930f4d1461032f5780631d62ebd9146103395780631e9b12ef146103695780631fab87c414610385578063233e9903146103a1575b600080fd5b610319610901565b6040516103269190613edd565b60405180910390f35b610337610907565b005b610353600480360381019061034e9190613f60565b610a75565b6040516103609190613edd565b60405180910390f35b610383600480360381019061037e9190613f60565b610ac1565b005b61039f600480360381019061039a9190613fb9565b610b44565b005b6103bb60048036038101906103b69190613fb9565b610b90565b005b6103d760048036038101906103d29190613fb9565b610bd9565b005b6103f360048036038101906103ee919061406a565b610e96565b005b6103fd6113eb565b005b610407611834565b005b610423600480360381019061041e919061411c565b6119c0565b005b61043f600480360381019061043a9190613f60565b611a2c565b60405161044c9190614164565b60405180910390f35b61046f600480360381019061046a9190613fb9565b611a49565b005b61048b6004803603810190610486919061417f565b611a92565b6040516104989190613edd565b60405180910390f35b6104bb60048036038101906104b6919061406a565b611abd565b005b6104d760048036038101906104d29190613f60565b611d0f565b6040516104e491906141ce565b60405180910390f35b61050760048036038101906105029190613f60565b611d42565b6040516105149190614164565b60405180910390f35b61053760048036038101906105329190613fb9565b611d62565b005b610541611dae565b60405161054e9190614164565b60405180910390f35b610571600480360381019061056c9190613f60565b611dc5565b60405161057e9190613edd565b60405180910390f35b6105a1600480360381019061059c91906141e9565b611e11565b6040516105af92919061423c565b60405180910390f35b6105c0611ec9565b005b6105ca611edd565b6040516105d791906142c4565b60405180910390f35b6105fa60048036038101906105f59190613f60565b611f03565b005b610604611fdc565b6040516106119190613edd565b60405180910390f35b610634600480360381019061062f9190613f60565b611fe2565b6040516106419190614164565b60405180910390f35b610652612063565b60405161065f919061439d565b60405180910390f35b610682600480360381019061067d9190614424565b612151565b005b61069e60048036038101906106999190614498565b612743565b005b6106a86128f1565b6040516106b59190614164565b60405180910390f35b6106c661292f565b6040516106d391906141ce565b60405180910390f35b6106e4612957565b6040516106f59594939291906144d8565b60405180910390f35b61071860048036038101906107139190613f60565b61297b565b005b6107226129fe565b60405161072f9190614164565b60405180910390f35b610752600480360381019061074d9190613fb9565b612a3b565b005b61075c612be5565b005b610766612d9f565b005b610770612e0c565b60405161077d91906141ce565b60405180910390f35b61078e612e32565b60405161079b9190613edd565b60405180910390f35b6107be60048036038101906107b9919061452b565b612e38565b005b6107c8612e60565b005b6107d26130f6565b005b6107dc6132ea565b6040516107e99190614644565b60405180910390f35b6107fa6132fd565b604051610807919061439d565b60405180910390f35b6108186133eb565b6040516108259190613edd565b60405180910390f35b61084860048036038101906108439190613fb9565b61342f565b005b610852613478565b005b61085c6134cd565b6040516108699190613edd565b60405180910390f35b61087a6134d3565b6040516108879190614164565b60405180910390f35b6108aa60048036038101906108a59190613f60565b61359e565b005b6108b4613621565b6040516108c19190614164565b60405180910390f35b6108e460048036038101906108df9190613f60565b61365f565b6040516108f898979695949392919061467d565b60405180910390f35b60085481565b60036002015443101561094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061477e565b60405180910390fd5b60006004811115610963576109626145cd565b5b600160159054906101000a900460ff166004811115610985576109846145cd565b5b14806109c45750600360048111156109a05761099f6145cd565b5b600160159054906101000a900460ff1660048111156109c2576109c16145cd565b5b145b610a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fa90614810565b60405180910390fd5b60018060156101000a81548160ff02191690836004811115610a2857610a276145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff16604051610a6b9190614644565b60405180910390a1565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b610ac9613703565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f9904a32444ae0eb0bae2045baf588aa248f03f4fef600c18afd1d7e751614af881604051610b3991906141ce565b60405180910390a150565b610b4c613703565b806003600401819055507f887fed3a9270ffbbf863d640a07413b6f58cf97afaa9d7267693e962a76bd81081604051610b859190613edd565b60405180910390a150565b610b98613703565b806009819055507fe933824a81d0b6aa53640e0e8df82b08c3f5297409b86d5beb73c41253518b2981604051610bce9190613edd565b60405180910390a150565b600260005403610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c159061487c565b60405180910390fd5b600260008190555060008111610c69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c60906148e8565b60405180910390fd5b60001515610c8133600c61378190919063ffffffff16565b151514610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba906149c6565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201541015610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614a32565b60405180910390fd5b80600a54610d569190614a81565b600a8190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610daa9190614a81565b601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550610e3d3382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d582604051610e839190613edd565b60405180910390a2600160008190555050565b600260005403610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed29061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050600954811015610f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6690614b27565b60405180910390fd5b60006004811115610f8357610f826145cd565b5b600160159054906101000a900460ff166004811115610fa557610fa46145cd565b5b1480610fe4575060036004811115610fc057610fbf6145cd565b5b600160159054906101000a900460ff166004811115610fe257610fe16145cd565b5b145b806110215750600480811115610ffd57610ffc6145cd565b5b600160159054906101000a900460ff16600481111561101f5761101e6145cd565b5b145b611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790614bb9565b60405180910390fd5b6000151561107833601061378190919063ffffffff16565b1515146110ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b190614c4b565b60405180910390fd5b86601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555085601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018190555033601360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061139633600e61383790919063ffffffff16565b503373ffffffffffffffffffffffffffffffffffffffff167f1dc186bd4daaf3fc4b9f8c689228a0be60dd2952dc502829514ae0d6955c0f5160405160405180910390a2506001600081905550505050505050565b600360020154431015611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142a9061477e565b60405180910390fd5b60026004811115611447576114466145cd565b5b600160159054906101000a900460ff166004811115611469576114686145cd565b5b146114a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a090614cdd565b60405180910390fd5b600115156114b56134d3565b1515146114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614d6f565b60405180910390fd5b6000611503600c613867565b905060005b8181101561168b57600061152682600c61387c90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b99190614dc8565b600a6115c59190614f28565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546008546116159190614f73565b61161f9190614fe4565b601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160008282546116709190615015565b9250508190555050808061168390615049565b915050611508565b505b6000611699600c613867565b11156116cd576116c76116b76000600c61387c90919063ffffffff16565b600c61389690919063ffffffff16565b5061168d565b6116d7600e613867565b905060005b8181101561178a5761170b6116fb82600e61387c90919063ffffffff16565b600c61383790919063ffffffff16565b5060006014600061172684600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061178290615049565b9150506116dc565b50600360010160008154809291906117a190615049565b9190505550600360000154436117b79190615015565b6003600201819055506000600160156101000a81548160ff021916908360048111156117e6576117e56145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516118299190614644565b60405180910390a150565b600260005403611879576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118709061487c565b60405180910390fd5b60026000819055506000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905060008111156119b5576000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506119663382600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166137b19092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516119ac9190613edd565b60405180910390a25b506001600081905550565b6119c8613703565b80600160156101000a81548160ff021916908360048111156119ed576119ec6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb681604051611a219190614644565b60405180910390a150565b6000611a4282600c61378190919063ffffffff16565b9050919050565b611a51613703565b806008819055507fc33a6daf06e5c2185564f32ef90cabd653cb01a6945c9d3c18a7481d20d3a0ed81604051611a879190613edd565b60405180910390a150565b6015602052816000526040600020602052806000526040600020600091509150508060000154905081565b85601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff16021790555084601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160046101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff16021790555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004018190555080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050181905550505050505050565b60136020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60146020528060005260406000206000915054906101000a900460ff1681565b611d6a613703565b806003600001819055507f5f15d41eab42cb3f8a5c9e8cd44043648cb85a815522c5f4ae5a32597a8447a081604051611da39190613edd565b60405180910390a150565b6000600160009054906101000a900460ff16905090565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b60008060006015600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905080600001548160010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250925050935093915050565b611ed1613703565b611edb60006138c6565b565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260005403611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9061487c565b60405180910390fd5b6002600081905550611f58613703565b611f6c81600e61389690919063ffffffff16565b50611f8181601061383790919063ffffffff16565b508073ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e976000604051611fc991906150cc565b60405180910390a2600160008190555050565b600a5481565b60008060156000600360010154815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506120446133eb565b81600001541061205857600191505061205e565b60009150505b919050565b60606000612071600c613867565b67ffffffffffffffff81111561208a576120896150e7565b5b6040519080825280602002602001820160405280156120b85781602001602082028036833780820191505090505b50905060006120c7600c613867565b905060005b81811015612148576120e881600c61387c90919063ffffffff16565b8382815181106120fb576120fa615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061214090615049565b9150506120cc565b50819250505090565b600260005403612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d9061487c565b60405180910390fd5b60026000819055506000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612271576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612268906151b7565b60405180910390fd5b61228581600e61378190919063ffffffff16565b6122c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bb9061526f565b60405180910390fd5b6000151560156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146123ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a490615301565b60405180910390fd5b60156000600360010154815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600081548092919061241690615049565b9190505550600160156000600360010154815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506124dd85600e61378190919063ffffffff16565b80156124ee57506124ed85611fe2565b5b156126cc5761250785600e61389690919063ffffffff16565b5061251c85601061383790919063ffffffff16565b5060006064600b54601260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201546125719190614f73565b61257b9190614fe4565b905080601260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546125cf9190614a81565b9250508190555080600a60008282546125e89190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040161264a9190613edd565b600060405180830381600087803b15801561266457600080fd5b505af1158015612678573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516126c29190613edd565b60405180910390a2505b838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167febdee48ed32f3feff81eed274b9e084b367ac42fe1cb710dcbd43f1d537d99fa868660405161272c92919061537f565b60405180910390a450600160008190555050505050565b600260005403612788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277f9061487c565b60405180910390fd5b6002600081905550612798613703565b80601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008282546127ea9190614a81565b9250508190555080600a60008282546128039190614a81565b92505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016128659190613edd565b600060405180830381600087803b15801561287f57600080fd5b505af1158015612893573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167ff020e162c28460a603e71f641a2e83634580ace02b9e28b844b2257949860e97826040516128dd9190613edd565b60405180910390a260016000819055505050565b600060016004811115612907576129066145cd565b5b600160159054906101000a900460ff166004811115612929576129286145cd565b5b14905090565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60038060000154908060010154908060020154908060030154908060040154905085565b612983613703565b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f2b5fe80d5061b20e017f0cde52b331309601bfcab0cb14cfcf6a4096410a6075816040516129f391906141ce565b60405180910390a150565b6000806004811115612a1357612a126145cd565b5b600160159054906101000a900460ff166004811115612a3557612a346145cd565b5b14905090565b600260005403612a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a779061487c565b60405180910390fd5b600260008190555060008111612acb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac2906153ef565b60405180910390fd5b612b1a333083600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613989909392919063ffffffff16565b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000828254612b6c9190615015565b9250508190555080600a6000828254612b859190615015565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d82604051612bd29190613edd565b60405180910390a2600160008190555050565b600260005403612c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c219061487c565b60405180910390fd5b600260008190555060006004811115612c4657612c456145cd565b5b600160159054906101000a900460ff166004811115612c6857612c676145cd565b5b1480612ca7575060036004811115612c8357612c826145cd565b5b600160159054906101000a900460ff166004811115612ca557612ca46145cd565b5b145b80612ce45750600480811115612cc057612cbf6145cd565b5b600160159054906101000a900460ff166004811115612ce257612ce16145cd565b5b145b612d23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1a90615481565b60405180910390fd5b612d3733600e61378190919063ffffffff16565b15612d5257612d5033600e61389690919063ffffffff16565b505b3373ffffffffffffffffffffffffffffffffffffffff167fff61c8020d05b8c2e31cdbb3d3f8cbcbdc57fcafa00229d9858b7cfd3b039c8a60405160405180910390a26001600081905550565b612da7613703565b6004600160156101000a81548160ff02191690836004811115612dcd57612dcc6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb66004604051612e029190614644565b60405180910390a1565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b612e40613a12565b612e4987612a3b565b612e57868686868686610e96565b50505050505050565b6000601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060016004811115612ed857612ed76145cd565b5b600160159054906101000a900460ff166004811115612efa57612ef96145cd565b5b1480612f39575060026004811115612f1557612f146145cd565b5b600160159054906101000a900460ff166004811115612f3757612f366145cd565b5b145b612f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6f90615513565b60405180910390fd5b600160036001015414612fd957612f9981600e61378190919063ffffffff16565b612fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fcf906155a5565b60405180910390fd5b5b6001601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f9784a0102afe6a5b031e774420da20a7d1e8207dde8e1ede9c6cefe5680ba05e60405160405180910390a261307c6134d3565b156130f3576002600160156101000a81548160ff021916908360048111156130a7576130a66145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516130ea9190614644565b60405180910390a15b50565b60036004015460036002015461310c9190615015565b43101561314e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131459061477e565b60405180910390fd5b60016004811115613162576131616145cd565b5b600160159054906101000a900460ff166004811115613184576131836145cd565b5b146131c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131bb90615637565b60405180910390fd5b60006131d0600e613867565b905060005b8181101561325b576000601460006131f784600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061325390615049565b9150506131d5565b5060038001600081548092919061327190615049565b91905055506003600160156101000a81548160ff0219169083600481111561329c5761329b6145cd565b5b02179055507f551dc40198cc79684bb69e4931dba4ac16e4598792ee1c0a5000aeea366d7bb6600160159054906101000a900460ff166040516132df9190614644565b60405180910390a150565b600160159054906101000a900460ff1681565b6060600061330b600e613867565b67ffffffffffffffff811115613324576133236150e7565b5b6040519080825280602002602001820160405280156133525781602001602082028036833780820191505090505b5090506000613361600e613867565b905060005b818110156133e25761338281600e61387c90919063ffffffff16565b83828151811061339557613394615116565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806133da90615049565b915050613366565b50819250505090565b600060026133f9600c613867565b11613407576001905061342c565b60036002613415600c613867565b61341f9190614f73565b6134299190614fe4565b90505b90565b613437613703565b80600b819055507fc0ff1deb4b889cc8d47d930be1a37c0e7442ab9850450d2dce635435c005e6a58160405161346d9190613edd565b60405180910390a150565b6134c3601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154610bd9565b6134cb611834565b565b60095481565b6000806000905060006134e6600e613867565b905060005b8181101561357a576014600061350b83600e61387c90919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561356757828061356390615049565b9350505b808061357290615049565b9150506134eb565b506135836133eb565b82106135945760019250505061359b565b6000925050505b90565b6135a6613703565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161360c906156c9565b60405180910390fd5b61361e816138c6565b50565b600060036004811115613637576136366145cd565b5b600160159054906101000a900460ff166004811115613659576136586145cd565b5b14905090565b60126020528060005260406000206000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046fffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905088565b61370b613a5c565b73ffffffffffffffffffffffffffffffffffffffff1661372961292f565b73ffffffffffffffffffffffffffffffffffffffff161461377f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161377690615735565b60405180910390fd5b565b60006137a9836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613a64565b905092915050565b6138328363a9059cbb60e01b84846040516024016137d0929190615755565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b505050565b600061385f836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613b4e565b905092915050565b600061387582600001613bbe565b9050919050565b600061388b8360000183613bcf565b60001c905092915050565b60006138be836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613bfa565b905092915050565b600060018054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816001806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a0c846323b872dd60e01b8585856040516024016139aa9392919061577e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613a87565b50505050565b613a1a611dae565b15613a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a5190615801565b60405180910390fd5b565b600033905090565b600080836001016000848152602001908152602001600020541415905092915050565b6000613ae9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613d0e9092919063ffffffff16565b9050600081511115613b495780806020019051810190613b09919061584d565b613b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b3f906158ec565b60405180910390fd5b5b505050565b6000613b5a8383613a64565b613bb3578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050613bb8565b600090505b92915050565b600081600001805490509050919050565b6000826000018281548110613be757613be6615116565b5b9060005260206000200154905092915050565b60008083600101600084815260200190815260200160002054905060008114613d02576000600182613c2c9190614a81565b9050600060018660000180549050613c449190614a81565b9050818114613cb3576000866000018281548110613c6557613c64615116565b5b9060005260206000200154905080876000018481548110613c8957613c88615116565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613cc757613cc661590c565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613d08565b60009150505b92915050565b6060613d1d8484600085613d26565b90509392505050565b606082471015613d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d62906159ad565b60405180910390fd5b613d7485613e3a565b613db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613daa90615a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ddc9190615aaa565b60006040518083038185875af1925050503d8060008114613e19576040519150601f19603f3d011682016040523d82523d6000602084013e613e1e565b606091505b5091509150613e2e828286613e5d565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315613e6d57829050613ebd565b600083511115613e805782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb49190615b05565b60405180910390fd5b9392505050565b6000819050919050565b613ed781613ec4565b82525050565b6000602082019050613ef26000830184613ece565b92915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613f2d82613f02565b9050919050565b613f3d81613f22565b8114613f4857600080fd5b50565b600081359050613f5a81613f34565b92915050565b600060208284031215613f7657613f75613ef8565b5b6000613f8484828501613f4b565b91505092915050565b613f9681613ec4565b8114613fa157600080fd5b50565b600081359050613fb381613f8d565b92915050565b600060208284031215613fcf57613fce613ef8565b5b6000613fdd84828501613fa4565b91505092915050565b600063ffffffff82169050919050565b613fff81613fe6565b811461400a57600080fd5b50565b60008135905061401c81613ff6565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61404781614022565b811461405257600080fd5b50565b6000813590506140648161403e565b92915050565b60008060008060008060c0878903121561408757614086613ef8565b5b600061409589828a0161400d565b96505060206140a689828a01614055565b95505060406140b789828a0161400d565b94505060606140c889828a01613f4b565b93505060806140d989828a01613fa4565b92505060a06140ea89828a01613fa4565b9150509295509295509295565b6005811061410457600080fd5b50565b600081359050614116816140f7565b92915050565b60006020828403121561413257614131613ef8565b5b600061414084828501614107565b91505092915050565b60008115159050919050565b61415e81614149565b82525050565b60006020820190506141796000830184614155565b92915050565b6000806040838503121561419657614195613ef8565b5b60006141a485828601613fa4565b92505060206141b585828601613f4b565b9150509250929050565b6141c881613f22565b82525050565b60006020820190506141e360008301846141bf565b92915050565b60008060006060848603121561420257614201613ef8565b5b600061421086828701613fa4565b935050602061422186828701613f4b565b925050604061423286828701613f4b565b9150509250925092565b60006040820190506142516000830185613ece565b61425e6020830184614155565b9392505050565b6000819050919050565b600061428a61428561428084613f02565b614265565b613f02565b9050919050565b600061429c8261426f565b9050919050565b60006142ae82614291565b9050919050565b6142be816142a3565b82525050565b60006020820190506142d960008301846142b5565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61431481613f22565b82525050565b6000614326838361430b565b60208301905092915050565b6000602082019050919050565b600061434a826142df565b61435481856142ea565b935061435f836142fb565b8060005b83811015614390578151614377888261431a565b975061438283614332565b925050600181019050614363565b5085935050505092915050565b600060208201905081810360008301526143b7818461433f565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126143e4576143e36143bf565b5b8235905067ffffffffffffffff811115614401576144006143c4565b5b60208301915083600182028301111561441d5761441c6143c9565b5b9250929050565b6000806000806060858703121561443e5761443d613ef8565b5b600061444c87828801613f4b565b945050602061445d87828801613fa4565b935050604085013567ffffffffffffffff81111561447e5761447d613efd565b5b61448a878288016143ce565b925092505092959194509250565b600080604083850312156144af576144ae613ef8565b5b60006144bd85828601613f4b565b92505060206144ce85828601613fa4565b9150509250929050565b600060a0820190506144ed6000830188613ece565b6144fa6020830187613ece565b6145076040830186613ece565b6145146060830185613ece565b6145216080830184613ece565b9695505050505050565b600080600080600080600060e0888a03121561454a57614549613ef8565b5b60006145588a828b01613fa4565b97505060206145698a828b0161400d565b965050604061457a8a828b01614055565b955050606061458b8a828b0161400d565b945050608061459c8a828b01613f4b565b93505060a06145ad8a828b01613fa4565b92505060c06145be8a828b01613fa4565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6005811061460d5761460c6145cd565b5b50565b600081905061461e826145fc565b919050565b600061462e82614610565b9050919050565b61463e81614623565b82525050565b60006020820190506146596000830184614635565b92915050565b61466881613fe6565b82525050565b61467781614022565b82525050565b600061010082019050614693600083018b61465f565b6146a0602083018a61466e565b6146ad604083018961465f565b6146ba60608301886141bf565b6146c76080830187613ece565b6146d460a0830186613ece565b6146e160c0830185613ece565b6146ee60e0830184613ece565b9998505050505050505050565b600082825260208201905092915050565b7f456e6f75676820626c6f636b732068617665206e6f7420656c6170736564207360008201527f696e636520746865206c6173742065706f636800000000000000000000000000602082015250565b60006147686033836146fb565b91506147738261470c565b604082019050919050565b600060208201905081810360008301526147978161475b565b9050919050565b7f4d75737420626520696e20616374697665206f7220756e6c6f636b656420737460008201527f6174650000000000000000000000000000000000000000000000000000000000602082015250565b60006147fa6023836146fb565b91506148058261479e565b604082019050919050565b60006020820190508181036000830152614829816147ed565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614866601f836146fb565b915061487182614830565b602082019050919050565b6000602082019050818103600083015261489581614859565b9050919050565b7f43616e6e6f742077697468647261772030000000000000000000000000000000600082015250565b60006148d26011836146fb565b91506148dd8261489c565b602082019050919050565b60006020820190508181036000830152614901816148c5565b9050919050565b7f4163746976652076616c696461746f72732063616e6e6f74206c656176652e2060008201527f20506c656173652075736520746865206c6561766528292066756e6374696f6e60208201527f20616e64207761697420666f7220746865206e6578742065706f636820746f2060408201527f6c65617665000000000000000000000000000000000000000000000000000000606082015250565b60006149b06065836146fb565b91506149bb82614908565b608082019050919050565b600060208201905081810360008301526149df816149a3565b9050919050565b7f4e6f7420656e6f75676820746f6b656e7320746f207769746864726177000000600082015250565b6000614a1c601d836146fb565b9150614a27826149e6565b602082019050919050565b60006020820190508181036000830152614a4b81614a0f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a8c82613ec4565b9150614a9783613ec4565b9250828203905081811115614aaf57614aae614a52565b5b92915050565b7f5374616b65206d7573742062652067726561746572207468616e206f7220657160008201527f75616c20746f206d696e696d756d5374616b6500000000000000000000000000602082015250565b6000614b116033836146fb565b9150614b1c82614ab5565b604082019050919050565b60006020820190508181036000830152614b4081614b04565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206a6f696e00000000000000000000602082015250565b6000614ba36036836146fb565b9150614bae82614b47565b604082019050919050565b60006020820190508181036000830152614bd281614b96565b9050919050565b7f596f752063616e6e6f742072656a6f696e20696620796f75206861766520626560008201527f656e206b69636b656420756e74696c20746865206e6578742065706f63680000602082015250565b6000614c35603e836146fb565b9150614c4082614bd9565b604082019050919050565b60006020820190508181036000830152614c6481614c28565b9050919050565b7f4d75737420626520696e20726561647920666f72206e6578742065706f63682060008201527f7374617465000000000000000000000000000000000000000000000000000000602082015250565b6000614cc76025836146fb565b9150614cd282614c6b565b604082019050919050565b60006020820190508181036000830152614cf681614cba565b9050919050565b7f4e6f7420656e6f7567682076616c696461746f7273206172652072656164792060008201527f666f7220746865206e6578742065706f63680000000000000000000000000000602082015250565b6000614d596032836146fb565b9150614d6482614cfd565b604082019050919050565b60006020820190508181036000830152614d8881614d4c565b9050919050565b600060ff82169050919050565b614da581614d8f565b8114614db057600080fd5b50565b600081519050614dc281614d9c565b92915050565b600060208284031215614dde57614ddd613ef8565b5b6000614dec84828501614db3565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115614e4c57808604811115614e2857614e27614a52565b5b6001851615614e375780820291505b8081029050614e4585614df5565b9450614e0c565b94509492505050565b600082614e655760019050614f21565b81614e735760009050614f21565b8160018114614e895760028114614e9357614ec2565b6001915050614f21565b60ff841115614ea557614ea4614a52565b5b8360020a915084821115614ebc57614ebb614a52565b5b50614f21565b5060208310610133831016604e8410600b8410161715614ef75782820a905083811115614ef257614ef1614a52565b5b614f21565b614f048484846001614e02565b92509050818404811115614f1b57614f1a614a52565b5b81810290505b9392505050565b6000614f3382613ec4565b9150614f3e83614d8f565b9250614f6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614e55565b905092915050565b6000614f7e82613ec4565b9150614f8983613ec4565b9250828202614f9781613ec4565b91508282048414831517614fae57614fad614a52565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614fef82613ec4565b9150614ffa83613ec4565b92508261500a57615009614fb5565b5b828204905092915050565b600061502082613ec4565b915061502b83613ec4565b925082820190508082111561504357615042614a52565b5b92915050565b600061505482613ec4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508657615085614a52565b5b600182019050919050565b6000819050919050565b60006150b66150b16150ac84615091565b614265565b613ec4565b9050919050565b6150c68161509b565b82525050565b60006020820190506150e160008301846150bd565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f436f756c64206e6f74206d617020796f7572206e6f646541646472657373207460008201527f6f20796f7572207374616b657241646472657373000000000000000000000000602082015250565b60006151a16034836146fb565b91506151ac82615145565b604082019050919050565b600060208201905081810360008301526151d081615194565b9050919050565b7f596f75206d75737420626520612076616c696461746f7220696e20746865206e60008201527f6578742065706f636820746f206b69636b20736f6d656f6e652066726f6d207460208201527f6865206e6578742065706f636800000000000000000000000000000000000000604082015250565b6000615259604d836146fb565b9150615264826151d7565b606082019050919050565b600060208201905081810360008301526152888161524c565b9050919050565b7f596f752063616e206f6e6c7920766f746520746f206b69636b20736f6d656f6e60008201527f65206f6e6365207065722065706f636800000000000000000000000000000000602082015250565b60006152eb6030836146fb565b91506152f68261528f565b604082019050919050565b6000602082019050818103600083015261531a816152de565b9050919050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061535e8385615321565b935061536b838584615332565b61537483615341565b840190509392505050565b6000602082019050818103600083015261539a818486615352565b90509392505050565b7f43616e6e6f74207374616b652030000000000000000000000000000000000000600082015250565b60006153d9600e836146fb565b91506153e4826153a3565b602082019050919050565b60006020820190508181036000830152615408816153cc565b9050919050565b7f4d75737420626520696e20416374697665206f7220556e6c6f636b656420737460008201527f61746520746f207265717565737420746f206c65617665000000000000000000602082015250565b600061546b6037836146fb565b91506154768261540f565b604082019050919050565b6000602082019050818103600083015261549a8161545e565b9050919050565b7f4d75737420626520696e207374617465204e65787456616c696461746f72536560008201527f744c6f636b6564206f72205265616479466f724e65787445706f636800000000602082015250565b60006154fd603c836146fb565b9150615508826154a1565b604082019050919050565b6000602082019050818103600083015261552c816154f0565b9050919050565b7f56616c696461746f72206973206e6f7420696e20746865206e6578742065706f60008201527f6368000000000000000000000000000000000000000000000000000000000000602082015250565b600061558f6022836146fb565b915061559a82615533565b604082019050919050565b600060208201905081810360008301526155be81615582565b9050919050565b7f4d75737420626520696e204e65787456616c696461746f725365744c6f636b6560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b60006156216021836146fb565b915061562c826155c5565b604082019050919050565b6000602082019050818103600083015261565081615614565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006156b36026836146fb565b91506156be82615657565b604082019050919050565b600060208201905081810360008301526156e2816156a6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061571f6020836146fb565b915061572a826156e9565b602082019050919050565b6000602082019050818103600083015261574e81615712565b9050919050565b600060408201905061576a60008301856141bf565b6157776020830184613ece565b9392505050565b600060608201905061579360008301866141bf565b6157a060208301856141bf565b6157ad6040830184613ece565b949350505050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006157eb6010836146fb565b91506157f6826157b5565b602082019050919050565b6000602082019050818103600083015261581a816157de565b9050919050565b61582a81614149565b811461583557600080fd5b50565b60008151905061584781615821565b92915050565b60006020828403121561586357615862613ef8565b5b600061587184828501615838565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006158d6602a836146fb565b91506158e18261587a565b604082019050919050565b60006020820190508181036000830152615905816158c9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006159976026836146fb565b91506159a28261593b565b604082019050919050565b600060208201905081810360008301526159c68161598a565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000615a03601d836146fb565b9150615a0e826159cd565b602082019050919050565b60006020820190508181036000830152615a32816159f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a6d578082015181840152602081019050615a52565b60008484015250505050565b6000615a8482615a39565b615a8e8185615a44565b9350615a9e818560208601615a4f565b80840191505092915050565b6000615ab68284615a79565b915081905092915050565b600081519050919050565b6000615ad782615ac1565b615ae181856146fb565b9350615af1818560208601615a4f565b615afa81615341565b840191505092915050565b60006020820190508181036000830152615b1f8184615acc565b90509291505056fea26469706673582212204882fa538c55ab56f1e64f81f9db5a68e93b40c4ee715f933a1609ca228180dd64736f6c63430008110033","abi":[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"EpochLengthSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"EpochTimeoutSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"KickPenaltyPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"MinimumStakeSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"ReadyForNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"}],"name":"RequestToLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"ResolverContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"StakingTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"StateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"TokenRewardPerTokenPerEpochSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBurned","type":"uint256"}],"name":"ValidatorKickedFromNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reporter","type":"address"},{"indexed":true,"internalType":"address","name":"validatorStakerAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"reason","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"VotedToKickValidatorInNextEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"}],"name":"adminKickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"amountToBurn","type":"uint256"}],"name":"adminSlashValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"advanceEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"epochLength","type":"uint256"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"retries","type":"uint256"},{"internalType":"uint256","name":"timeout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValidatorsInCurrentEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidatorsInNextEpoch","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochNumber","type":"uint256"},{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"address","name":"voterStakerAddress","type":"address"}],"name":"getVotingStatusToKickValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isActiveValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReadyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickPenaltyPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorStakerAddress","type":"address"},{"internalType":"uint256","name":"reason","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"kickValidatorInNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nodeAddressToStakerAddress","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":"pauseEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readyForNextEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"requestToJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestToLeave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolverContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochLength","type":"uint256"}],"name":"setEpochLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Staking.States","name":"newState","type":"uint8"}],"name":"setEpochState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newEpochTimeout","type":"uint256"}],"name":"setEpochTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"setIpPortNodeAddressAndCommunicationPubKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newKickPenaltyPercent","type":"uint256"}],"name":"setKickPenaltyPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimumStake","type":"uint256"}],"name":"setMinimumStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newResolverContractAddress","type":"address"}],"name":"setResolverContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStakingTokenAddress","type":"address"}],"name":"setStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTokenRewardPerTokenPerEpoch","type":"uint256"}],"name":"setTokenRewardPerTokenPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"shouldKickValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signalReadyForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"name":"stakeAndJoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract LITToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Staking.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenRewardPerTokenPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockValidatorsForNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorCountForConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorStateIsUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validators","outputs":[{"internalType":"uint32","name":"ip","type":"uint32"},{"internalType":"uint128","name":"ipv6","type":"uint128"},{"internalType":"uint32","name":"port","type":"uint32"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"senderPubKey","type":"uint256"},{"internalType":"uint256","name":"receiverPubKey","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsInNextEpochAreLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votesToKickValidatorsInNextEpoch","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/gas_costs.txt b/gas_costs.txt index 3070d72..e33eece 100644 --- a/gas_costs.txt +++ b/gas_costs.txt @@ -1,22 +1,198 @@ - AccessControlConditions - storeAndRetrieveCondition - when unauthorized - ✓ retrieves empty condition - when key is correct and condition is not permanent - ✓ retrieves condition and updates it - when key is correct and condition is permanent - ✓ retrieves condition and attempts to update it - Store condition with signer and retrieve - when key is incorrect - ✓ retrieves empty condition - when signer is unauthorized - ✓ fails to store condition with signer - when key is correct and condition is not permanent - ✓ retrieves condition and fails to update it with incorrect creator - ✓ retrieves condition and fails to update it with correct creator - when key is correct and condition is permanent - ✓ retrieves condition and fails to update it + DomainWalletOracle + ✓ should register uri + + DomainWalletRegistry +DiamondCutFacet deployed: 0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82 +DiamondLoupeFacetNoERC165 deployed: 0x9A676e781A523b5d0C0e43731313A708CB607508 +OwnershipFacet deployed: 0x0B306BF915C4d645ff596e518fAf3F9669b97016 +PKPNFTFacet deployed: 0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1 +DiamondCutFacet deployed: 0x3Aa5ebB10DC797CAC828524e59A333d0A371443c +DiamondLoupeFacet deployed: 0xc6e7DF5E7b4f2A278906862b61205850344D4e7d +OwnershipFacet deployed: 0x59b670e9fA9D0A427751Af201D676719a970857b +PubkeyRouterFacet deployed: 0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1 +DiamondCutFacet deployed: 0x4A679253410272dd5232B3Ff7cF5dbB88f295319 +DiamondLoupeFacet deployed: 0x7a2088a1bFc9d81c55368AE168C2C02570cB814F +OwnershipFacet deployed: 0x09635F643e140090A9A8Dcd712eD6285858ceBef +PKPPermissionsFacet deployed: 0xc5a5C42992dECbae36851359345FE25997F5C42d +BigNumber { value: "1" } + ✓ should register uri +DiamondCutFacet deployed: 0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575 +DiamondLoupeFacetNoERC165 deployed: 0xCD8a1C3ba11CF5ECfa6267617243239504a98d90 +OwnershipFacet deployed: 0x82e01223d51Eb87e16A03E24687EDF0F294da6f1 +PKPNFTFacet deployed: 0x2bdCC0de6bE1f7D2ee689a0342D76F52E8EFABa3 +DiamondCutFacet deployed: 0xc351628EB244ec633d5f21fBD6621e1a683B1181 +DiamondLoupeFacet deployed: 0xFD471836031dc5108809D173A067e8486B9047A3 +OwnershipFacet deployed: 0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc +PubkeyRouterFacet deployed: 0x1429859428C0aBc9C2C47C8Ee9FBaf82cFA0F20f +DiamondCutFacet deployed: 0x922D6956C99E12DFeB3224DEA977D0939758A1Fe +DiamondLoupeFacet deployed: 0x5081a39b8A5f0E35a8D959395a630b68B74Dd30f +OwnershipFacet deployed: 0x1fA02b2d6A771842690194Cf62D91bdd92BfE28d +PKPPermissionsFacet deployed: 0xdbC43Ba45381e02825b14322cDdd15eC4B3164E6 + ✓ converted expirery should match registration expirery time +DiamondCutFacet deployed: 0x7A9Ec1d04904907De0ED7b6839CcdD59c3716AC9 +DiamondLoupeFacetNoERC165 deployed: 0x49fd2BE640DB2910c2fAb69bB8531Ab6E76127ff +OwnershipFacet deployed: 0x4631BCAbD6dF18D94796344963cB60d44a4136b6 +PKPNFTFacet deployed: 0x86A2EE8FAf9A840F7a2c64CA3d51209F9A02081D +DiamondCutFacet deployed: 0xAA292E8611aDF267e563f334Ee42320aC96D0463 +DiamondLoupeFacet deployed: 0x5c74c94173F05dA1720953407cbb920F3DF9f887 +OwnershipFacet deployed: 0x720472c8ce72c2A2D711333e064ABD3E6BbEAdd3 +PubkeyRouterFacet deployed: 0xe8D2A1E88c91DCd5433208d4152Cc4F399a7e91d +DiamondCutFacet deployed: 0x4b6aB5F819A515382B0dEB6935D793817bB4af28 +DiamondLoupeFacet deployed: 0xCace1b78160AE76398F486c8a18044da0d66d86D +OwnershipFacet deployed: 0xD5ac451B0c50B9476107823Af206eD814a2e2580 +PKPPermissionsFacet deployed: 0xF8e31cb472bc70500f08Cd84917E5A1912Ec8397 + ✓ revoked domain should not be routed +DiamondCutFacet deployed: 0x8A93d247134d91e0de6f96547cB0204e5BE8e5D8 +DiamondLoupeFacetNoERC165 deployed: 0x40918Ba7f132E0aCba2CE4de4c4baF9BD2D7D849 +OwnershipFacet deployed: 0xF32D39ff9f6Aa7a7A64d7a4F00a54826Ef791a55 +PKPNFTFacet deployed: 0xd6e1afe5cA8D00A2EFC01B89997abE2De47fdfAf +DiamondCutFacet deployed: 0xCA8c8688914e0F7096c920146cd0Ad85cD7Ae8b9 +DiamondLoupeFacet deployed: 0xB0f05d25e41FbC2b52013099ED9616f1206Ae21B +OwnershipFacet deployed: 0x5FeaeBfB4439F3516c74939A9D04e95AFE82C4ae +PubkeyRouterFacet deployed: 0x976fcd02f7C4773dd89C309fBF55D5923B4c98a1 +DiamondCutFacet deployed: 0xfcDB4564c18A9134002b9771816092C9693622e3 +DiamondLoupeFacet deployed: 0x927b167526bAbB9be047421db732C663a0b77B11 +OwnershipFacet deployed: 0x32EEce76C2C2e8758584A83Ee2F522D4788feA0f +PKPPermissionsFacet deployed: 0x01c1DeF3b91672704716159C9041Aeca392DdFfb + ✓ revoked domain should not be have owner +DiamondCutFacet deployed: 0x70bDA08DBe07363968e9EE53d899dFE48560605B +DiamondLoupeFacetNoERC165 deployed: 0x26B862f640357268Bd2d9E95bc81553a2Aa81D7E +OwnershipFacet deployed: 0xA56F946D6398Dd7d9D4D9B337Cf9E0F68982ca5B +PKPNFTFacet deployed: 0x5D42EBdBBa61412295D7b0302d6F50aC449Ddb4F +DiamondCutFacet deployed: 0xaB7B4c595d3cE8C85e16DA86630f2fc223B05057 +DiamondLoupeFacet deployed: 0xAD523115cd35a8d4E60B3C0953E0E0ac10418309 +OwnershipFacet deployed: 0x045857BDEAE7C1c7252d611eB24eB55564198b4C +PubkeyRouterFacet deployed: 0x2b5A4e5493d4a54E717057B127cf0C000C876f9B +DiamondCutFacet deployed: 0x821f3361D454cc98b7555221A06Be563a7E2E0A6 +DiamondLoupeFacet deployed: 0x1780bCf4103D3F501463AD3414c7f4b654bb7aFd +OwnershipFacet deployed: 0x5133BBdfCCa3Eb4F739D599ee4eC45cBCD0E16c5 +PKPPermissionsFacet deployed: 0x71089Ba41e478702e1904692385Be3972B2cBf9e + ✓ registered domain should have pkp owner +DiamondCutFacet deployed: 0x2625760C4A8e8101801D3a48eE64B2bEA42f1E96 +DiamondLoupeFacetNoERC165 deployed: 0xFE5f411481565fbF70D8D33D992C78196E014b90 +OwnershipFacet deployed: 0xD6b040736e948621c5b6E0a494473c47a6113eA8 +PKPNFTFacet deployed: 0x139e1D41943ee15dDe4DF876f9d0E7F85e26660A +DiamondCutFacet deployed: 0xcE0066b1008237625dDDBE4a751827de037E53D2 +DiamondLoupeFacet deployed: 0x82EdA215Fa92B45a3a76837C65Ab862b6C7564a8 +OwnershipFacet deployed: 0x87006e75a5B6bE9D1bbF61AC8Cd84f05D9140589 +PubkeyRouterFacet deployed: 0x51C65cd0Cdb1A8A8b79dfc2eE965B1bA0bb8fc89 +DiamondCutFacet deployed: 0x359570B3a0437805D0a71457D61AD26a28cAC9A2 +DiamondLoupeFacet deployed: 0xc9952Fc93Fa9bE383ccB39008c786b9f94eAc95d +OwnershipFacet deployed: 0xDde063eBe8E85D666AD99f731B4Dbf8C98F29708 +PKPPermissionsFacet deployed: 0xD5724171C2b7f0AA717a324626050BD05767e2C6 + ✓ Should not mint if domain is registered +DiamondCutFacet deployed: 0x71a0b8A2245A9770A4D887cE1E4eCc6C1d4FF28c +DiamondLoupeFacetNoERC165 deployed: 0xb185E9f6531BA9877741022C92CE858cDCc5760E +OwnershipFacet deployed: 0xAe120F0df055428E45b264E7794A18c54a2a3fAF +PKPNFTFacet deployed: 0x193521C8934bCF3473453AF4321911E7A89E0E12 +DiamondCutFacet deployed: 0x3C1Cb427D20F15563aDa8C249E71db76d7183B6c +DiamondLoupeFacet deployed: 0x1343248Cbd4e291C6979e70a138f4c774e902561 +OwnershipFacet deployed: 0x22a9B82A6c3D2BFB68F324B2e8367f346Dd6f32a +PubkeyRouterFacet deployed: 0x547382C0D1b23f707918D3c83A77317B71Aa8470 +DiamondCutFacet deployed: 0x5e6CB7E728E1C320855587E1D9C6F7972ebdD6D5 +DiamondLoupeFacet deployed: 0x79E8AB29Ff79805025c9462a2f2F12e9A496f81d +OwnershipFacet deployed: 0x0Dd99d9f56A14E9D53b2DdC62D9f0bAbe806647A +PKPPermissionsFacet deployed: 0xeAd789bd8Ce8b9E94F5D0FCa99F8787c7e758817 + ✓ registered domain expirey should be true +DiamondCutFacet deployed: 0x666D0c3da3dBc946D5128D06115bb4eed4595580 +DiamondLoupeFacetNoERC165 deployed: 0x742489F22807ebB4C36ca6cD95c3e1C044B7B6c8 +OwnershipFacet deployed: 0x1D8D70AD07C8E7E442AD78E4AC0A16f958Eba7F0 +PKPNFTFacet deployed: 0xA9e6Bfa2BF53dE88FEb19761D9b2eE2e821bF1Bf +DiamondCutFacet deployed: 0x286B8DecD5ED79c962b2d8F4346CD97FF0E2C352 +DiamondLoupeFacet deployed: 0xb868Cc77A95a65F42611724AF05Aa2d3B6Ec05F2 +OwnershipFacet deployed: 0x70E5370b8981Abc6e14C91F4AcE823954EFC8eA3 +PubkeyRouterFacet deployed: 0x4000F8820522AC96C4221b299876e3e53bCc8525 +DiamondCutFacet deployed: 0x7Cf4be31f546c04787886358b9486ca3d62B9acf +DiamondLoupeFacet deployed: 0x33E45b187da34826aBCEDA1039231Be46f1b05Af +OwnershipFacet deployed: 0x0c626FC4A447b01554518550e30600136864640B +PKPPermissionsFacet deployed: 0xA21DDc1f17dF41589BC6A5209292AED2dF61Cc94 + ✓ Should not register domain already registered + + ContractResolver + set contract + with a valid environment + ✓ creates an address mapping + without role + ✓ produces an error + get contract + with an existing contract + ✓ returns a contract address + when no contract exists + ✓ returns an empty address + add allowed env + with valid env + ✓ will allow release for env + remove allowed env + with valid env + ✓ will prevent release for env + + ReleaseRegister + init creator + having a valid role and called the first time + ✓ will succeed + without a valid role + ✓ will fail + when called more than once + ✓ will fail + create release + when no existing release + ✓ creates a release + ✓ creates a release with specific date + ✓ creates a custom release with a kind + with an existing release + ✓ produces an error + with an invalid status + ✓ produces an error + with an invalid env + ✓ produces an error + without role + ✓ produces an error + set release status + with Active status and release + ✓ will set the status + with Disabled status and release + ✓ will set the status + when release doesn't exist + ✓ produces an error + with an invalid status + ✓ produces an error + without ACTIVATOR role + ✓ produces an error + without DEACTIVATOR role + ✓ produces an error + burn release + with valid release + ✓ will burn the release + when release doesn't exist + ✓ produces an error + without role + ✓ produces an error + get active release + with a set of releases + ✓ will find an active node release + ✓ will find an active prov release + ✓ will find an active build release + ✓ will find an active custom salt-master release + ✓ will return a list of active release ids + add allowed env + with valid env + ✓ will allow release for env + remove allowed env + with valid env + ✓ will prevent release for env + add allowed subnet + with valid subnet + ✓ will allow release for env + remove allowed subnet + with valid subnet + ✓ will prevent release for env + add allowed admin signing public key + with valid public key + ✓ will add allowed public key + remove allowed admin signing public key + with valid public key + ✓ will remove allowed address Allowlist Test the Allowlist @@ -38,259 +214,572 @@ PKPHelper Attempt to Mint PKP NFT via PKPHelper +DiamondCutFacet deployed: 0x837a41023CF81234f89F956C94D676918b4791c1 +DiamondLoupeFacetNoERC165 deployed: 0x04d7478fDF318C3C22cECE62Da9D78ff94807D77 +OwnershipFacet deployed: 0xd9abC93F81394Bd161a1b24B03518e0a570bDEAd +PKPNFTFacet deployed: 0xcB0f2a13098f8e841e6Adfa5B17Ec00508b27665 +DiamondCutFacet deployed: 0x87c470437282174b3f8368c7CF1Ac03bcAe57954 +DiamondLoupeFacet deployed: 0x746a48E39dC57Ff14B872B8979E20efE5E5100B1 +OwnershipFacet deployed: 0x96E303b6D807c0824E83f954784e2d6f3614f167 +PubkeyRouterFacet deployed: 0x9CC8B5379C40E24F374cd55973c138fff83ed214 +DiamondCutFacet deployed: 0x930b218f3e63eE452c13561057a8d5E61367d5b7 +DiamondLoupeFacet deployed: 0x721d8077771Ebf9B931733986d619aceea412a1C +OwnershipFacet deployed: 0x38c76A767d45Fc390160449948aF80569E2C4217 +PKPPermissionsFacet deployed: 0xDC57724Ea354ec925BaFfCA0cCf8A1248a8E5CF1 ✓ mints successfully with permitted auth methods +DiamondCutFacet deployed: 0x72662E4da74278430123cE51405c1e7A1B87C294 +DiamondLoupeFacetNoERC165 deployed: 0x52bad4A8584909895C22bdEcf8DBF33314468Fb0 +OwnershipFacet deployed: 0xed12bE400A07910E4d4E743E4ceE26ab1FC9a961 +PKPNFTFacet deployed: 0x1B25157F05B25438441bF7CDe38A95A55ccf8E50 +DiamondCutFacet deployed: 0x32cd5ecdA7f2B8633C00A0434DE28Db111E60636 +DiamondLoupeFacet deployed: 0xbeC6419cD931e29ef41157fe24C6928a0C952f0b +OwnershipFacet deployed: 0x55027d3dBBcEA0327eF73eFd74ba0Af42A13A966 +PubkeyRouterFacet deployed: 0x9eb52339B52e71B1EFD5537947e75D23b3a7719B +DiamondCutFacet deployed: 0x1Dbbf529D78d6507B0dd71F6c02f41138d828990 +DiamondLoupeFacet deployed: 0xf18774574148852771c2631d7d06E2A6c8b44fCA +OwnershipFacet deployed: 0x9f62EE65a8395824Ee0821eF2Dc4C947a23F0f25 +PKPPermissionsFacet deployed: 0x20BBE62B175134D21b10C157498b663F048672bA ✓ mints successfully with permitted auth methods using the simple non-typed function +DiamondCutFacet deployed: 0x7c02b58029beeA7c1FcC872803dC9818f57A0E61 +DiamondLoupeFacetNoERC165 deployed: 0x3818eAb6Ca8Bf427222bfACFA706c514145F4104 +OwnershipFacet deployed: 0x4A351C6aE3249499CBb50E8FE6566E2615386Da8 +PKPNFTFacet deployed: 0xa8fcCF4D0e2f2c4451123fF2F9ddFc9be465Fa1d +DiamondCutFacet deployed: 0x0aD6371dd7E9923d9968D63Eb8B9858c700abD9d +DiamondLoupeFacet deployed: 0xAA5c5496e2586F81d8d2d0B970eB85aB088639c2 +OwnershipFacet deployed: 0xa95A928eEc085801d981d13FFE749872D8FD5bec +PubkeyRouterFacet deployed: 0x575D3d18666B28680255a202fB5d482D1949bB32 +DiamondCutFacet deployed: 0x721a1ecB9105f2335a8EA7505D343a5a09803A06 +DiamondLoupeFacet deployed: 0x9852795dbb01913439f534b4984fBf74aC8AfA12 +OwnershipFacet deployed: 0x889D9A5AF83525a2275e41464FAECcCb3337fF60 +PKPPermissionsFacet deployed: 0xf274De14171Ab928A5Ec19928cE35FaD91a42B64 ✓ mints successfully with permitted auth methods and sends the PKP to itself +DiamondCutFacet deployed: 0x02e8910B3B89690d4aeC9fcC0Ae2cD16fB6A4828 +DiamondLoupeFacetNoERC165 deployed: 0x564Db7a11653228164FD03BcA60465270E67b3d7 +OwnershipFacet deployed: 0x9abb5861e3a1eDF19C51F8Ac74A81782e94F8FdC +PKPNFTFacet deployed: 0x484242986F57dFcA98EeC2C78427931C63F1C4ce +DiamondCutFacet deployed: 0x8B342f4Ddcc71Af65e4D2dA9CD00cc0E945cFD12 +DiamondLoupeFacet deployed: 0xE2307e3710d108ceC7a4722a020a050681c835b3 +OwnershipFacet deployed: 0xD28F3246f047Efd4059B24FA1fa587eD9fa3e77F +PubkeyRouterFacet deployed: 0x15F2ea83eB97ede71d84Bd04fFF29444f6b7cd52 +DiamondCutFacet deployed: 0x519b05b3655F4b89731B677d64CEcf761f4076f6 +DiamondLoupeFacet deployed: 0x057cD3082EfED32d5C907801BF3628B27D88fD80 +OwnershipFacet deployed: 0xb6057e08a11da09a998985874FE2119e98dB3D5D +PKPPermissionsFacet deployed: 0xad203b3144f8c09a20532957174fc0366291643c ✓ mints without setting the pkp nft address as permitted +DiamondCutFacet deployed: 0xBe6Eb4ACB499f992ba2DaC7CAD59d56DA9e0D823 +DiamondLoupeFacetNoERC165 deployed: 0x54287AaB4D98eA51a3B1FBceE56dAf27E04a56A6 +OwnershipFacet deployed: 0xE401FBb0d6828e9f25481efDc9dd18Da9E500983 +PKPNFTFacet deployed: 0xb6aA91E8904d691a10372706e57aE1b390D26353 +DiamondCutFacet deployed: 0x4c04377f90Eb1E42D845AB21De874803B8773669 +DiamondLoupeFacet deployed: 0xf93b0549cD50c849D792f0eAE94A598fA77C7718 +OwnershipFacet deployed: 0x8CeA85eC7f3D314c4d144e34F2206C8Ac0bbadA1 +PubkeyRouterFacet deployed: 0x29023DE63D7075B4cC2CE30B55f050f9c67548d4 +DiamondCutFacet deployed: 0x7A5EC257391817ef241ef8451642cC6b222d4f8C +DiamondLoupeFacet deployed: 0x90E75f390332356426B60FB440DF23f860F6A113 +OwnershipFacet deployed: 0x59c7D03d2E9893FB7bAa89dA50a9452e1e9B8b90 +PKPPermissionsFacet deployed: 0x834Ea01e45F9b5365314358159d92d134d89feEb ✓ mints successfully with empty auth methods PKPNFT Attempt to Mint PKP NFT +DiamondCutFacet deployed: 0x798f111c92E38F102931F34D1e0ea7e671BDBE31 +DiamondLoupeFacetNoERC165 deployed: 0xabebE9a2D62Af9a89E86EB208b51321e748640C3 +OwnershipFacet deployed: 0xf42Ec71A4440F5e9871C643696DD6Dc9a38911F8 +PKPNFTFacet deployed: 0xbc71F5687CFD36f64Ae6B4549186EE3A6eE259a4 +DiamondCutFacet deployed: 0x82A9286dB983093Ff234cefCea1d8fA66382876B +DiamondLoupeFacet deployed: 0x41219a0a9C0b86ED81933c788a6B63Dfef8f17eE +OwnershipFacet deployed: 0x1d460d731Bd5a0fF2cA07309dAEB8641a7b175A1 +PubkeyRouterFacet deployed: 0xF67e26649037695DdFAB19f4E22d5c9Fd1564592 +DiamondCutFacet deployed: 0x18b7CBdfFA52d1e7BB992fd50f394c5b59E20B72 +DiamondLoupeFacet deployed: 0x2f321ed425c82E74925488139e1556f9B76a2551 +OwnershipFacet deployed: 0x776D6996c8180838dC0587aE0DE5D614b1350f37 +PKPPermissionsFacet deployed: 0x3A906C603F080D96dc08f81CF2889dAB6FF299dE ✓ refuses to mint for free - ✓ refuses to mint because the PKP isnt routed yet -getting token uri -got pubkey, getting eth address -calling tokenURI +DiamondCutFacet deployed: 0xcE7e5946C14Cdd1f8de4473dB9c20fd65EBd47d0 +DiamondLoupeFacetNoERC165 deployed: 0xA496E0071780CF57cd699cb1D5Ac0CdCD6cCD673 +OwnershipFacet deployed: 0x4E76FbE44fa5Dae076a7f4f676250e7941421fbA +PKPNFTFacet deployed: 0x00B0517de6b2b09aBD3a7B69d66D85eFdb2c7d94 +DiamondCutFacet deployed: 0x06786bCbc114bbfa670E30A1AC35dFd1310Be82f +DiamondLoupeFacet deployed: 0x72F853E9E202600c5017B5A060168603c3ed7368 +OwnershipFacet deployed: 0x82Bd83ec6D4bCC8EaB6F6cF7565efE1e41D92Ce5 +PubkeyRouterFacet deployed: 0xD61210E756f7D71Cc4F74abF0747D65Ea9d7525b +DiamondCutFacet deployed: 0xA3b48c7b901fede641B596A4C10a4630052449A6 +DiamondLoupeFacet deployed: 0xa138575a030a2F4977D19Cc900781E7BE3fD2bc0 +OwnershipFacet deployed: 0xB8d6D6b01bFe81784BE46e5771eF017Fa3c906d8 +PKPPermissionsFacet deployed: 0xf524930660f75CF602e909C15528d58459AB2A56 + ✓ mints successfully + Attempt to claim derived PKP NFT +DiamondCutFacet deployed: 0xC54051689e0931FdCF3e708b665f521f7ab42Fb0 +DiamondLoupeFacetNoERC165 deployed: 0x00436c9F57dfFd96cECd129c04D9E488c57266cF +OwnershipFacet deployed: 0xe4a4B3Bc2787aA913e5b4bbce907e8b213250BDe +PKPNFTFacet deployed: 0xD962a5F050A5F0a2f8dF82aFc04CF1afFE585082 +DiamondCutFacet deployed: 0xa591098680B1e183C332Ea8e2612a2Cf2e6ABC17 +DiamondLoupeFacet deployed: 0xdABF214E5a833269c192D9d70efDdE174680628D +OwnershipFacet deployed: 0x645D817611E0CDaF9cD43332c4E369B9E333471d +PubkeyRouterFacet deployed: 0x81F82957608f74441E085851cA5Cc091b23d17A2 +DiamondCutFacet deployed: 0xA3E5DfE71aE3e6DeC4D98fa28821dF355d7244B3 +DiamondLoupeFacet deployed: 0x69F94e46cbC82Ab02781ac4FaFc3580d21f1a888 +OwnershipFacet deployed: 0xE0a1556ef66873d965A2F4caD06F051646BE6707 +PKPPermissionsFacet deployed: 0x5BFaaA02cAb795d576276a19CB1c2D2D2d652717 ✓ mints successfully - Test free minting of PKP NFT - ✓ refuses to mint with an empty sig -sig 0xd1fc6602618728eb9cafd429425cb19b27a2824d0fea729dcbe10e45f2a0014d700ae15d5ce29af6e798365e703ca626a52522b38a72ec91c957d848858a70ab1c -r: 0xd1fc6602618728eb9cafd429425cb19b27a2824d0fea729dcbe10e45f2a0014d -s: 0x700ae15d5ce29af6e798365e703ca626a52522b38a72ec91c957d848858a70ab -v: 0x1c - ✓ checks the signature for a free mint Test Mint Grant And Burn +DiamondCutFacet deployed: 0x72aC6A36de2f72BD39e9c782e9db0DCc41FEbfe2 +DiamondLoupeFacetNoERC165 deployed: 0xAAd4F7BB5FB661181D500829e60010043833a85B +OwnershipFacet deployed: 0x4Bd915C3e39cfF4eac842255965E79061c38cACD +PKPNFTFacet deployed: 0x2B64822cf4bbDd77d386F51AA2B40c5cdbeb80b5 +DiamondCutFacet deployed: 0xBc153693BFAe1Ca202872a382aED20a1306C9200 +DiamondLoupeFacet deployed: 0xd8E4Af8145A8288537B85878bb2371fa070Aa5eF +OwnershipFacet deployed: 0xE634d83f8E016B04e51F2516e6086b5f238675C7 +PubkeyRouterFacet deployed: 0x86c64cB21f88fA9E2c46b61c35889E75f08FDce1 +DiamondCutFacet deployed: 0x1966dc8ff30Bc4AeDEd27178642253b3cCC9AA3f +DiamondLoupeFacet deployed: 0x5f58879Fe3a4330B6D85c1015971Ea6e5175AeDD +OwnershipFacet deployed: 0x582957C7a35CDfeAAD1Ca4b87AE03913eAAd0Be0 +PKPPermissionsFacet deployed: 0x63ecE4C05B8fB272D16844E96702Ea2f26370982 ✓ mints, grants, and burns successfully PKPPermissions +DiamondCutFacet deployed: 0x3CA5269B5c54d4C807Ca0dF7EeB2CB7a5327E77d +DiamondLoupeFacetNoERC165 deployed: 0x8a6E9a8E0bB561f8cdAb1619ECc4585aaF126D73 +OwnershipFacet deployed: 0xf09e7Af8b380cD01BD0d009F83a6b668A47742ec +PKPNFTFacet deployed: 0x492844c46CEf2d751433739fc3409B7A4a5ba9A7 +DiamondCutFacet deployed: 0xe58cBE144dD5556C84874deC1b3F2d0D6Ac45F1b +DiamondLoupeFacet deployed: 0xDC0a0B1Cd093d321bD1044B5e0Acb71b525ABb6b +OwnershipFacet deployed: 0xDe1112a0960B9619da7F91D51fB571cdefE48B5E +PubkeyRouterFacet deployed: 0x1D87585dF4D48E52436e26521a3C5856E4553e3F +DiamondCutFacet deployed: 0x9A8Ec3B44ee760b629e204900c86d67414a67e8f +DiamondLoupeFacet deployed: 0xA899118f4BCCb62F8c6A37887a4F450D8a4E92E0 +OwnershipFacet deployed: 0xb60971942E4528A811D24826768Bc91ad1383D21 +PKPPermissionsFacet deployed: 0xD185B4846E5fd5419fD4D077dc636084BEfC51C0 register a PKP and set routing permissions when the PKP grants permission to an ETH address ✓ grants permission to an eth address and then revokes it ✓ grants permission to an IPFS id and then revokes it - ✓ grants permission to an IPFS id and then revokes it - ✓ registers and grants permission to a generic AuthMethod + ✓ registers and grants permission to a webauthn AuthMethod ✓ registers and grants permission to a generic AuthMethod with scopes + ✓ registers and grants permission to a generic AuthMethod using batch methods ✓ updates root hash and verify state - register a PKP and set routing permissions for a burn test - when the PKP grants permission to an ETH address ✓ grants permission to an eth address and then revokes it and then burns it PubkeyRouter +DiamondCutFacet deployed: 0x8659DF1C638CDA8E475CD3C6481730C2b4f85873 +DiamondLoupeFacetNoERC165 deployed: 0x1f9c84B161b2c7FFB540BC5354543108cCE37df1 +OwnershipFacet deployed: 0x4D1338Fa46ca6060F1472b70599cc635Ad275EDa +PKPNFTFacet deployed: 0x87E8f332f34984728Da4c0A008a495A5Ec4E09a2 +DiamondCutFacet deployed: 0x53DaB165b879542E9aDFC41c6474A9d797B9b042 +DiamondLoupeFacet deployed: 0x03F7F064E6ceD8e154e3FdAAF92DcCC4e818E97B +OwnershipFacet deployed: 0x4BEA9aAe24187d6128403DC556510A18d727871a +PubkeyRouterFacet deployed: 0x6cD036fDBD89BaA51c8722Eec0B56CeEd301cC68 +DiamondCutFacet deployed: 0x295129609d6876f5ECC62052Ba6bc082139A982c +DiamondLoupeFacet deployed: 0xB92257D74B8815EC711071889cB506C8d66A6a06 +OwnershipFacet deployed: 0x737b8F095E3c575a6Ae5FE1711AdB8F271E20269 +PKPPermissionsFacet deployed: 0xAd3E631c01798f9aAE4692dabF791a62c226C5D4 store and retrieve routing data when routing data is unset ✓ retrieves empty routing data - when routing data is set - ✓ sets and retrieves routing data - register a PKP and set routing permissions - when the PKP is minted, check the ETH address -fakePubkey 0x046db7b0736408e7874b746f6d54aa6e4d04fd8902b520af69493f62757e77e0b5247355f925af2b382b64c71fcb3ff3ad26469ca65b4d2945d6e6379a4f285b93 -ethersResult 0xCFcf34ED9b3A5EaCCa536a8C67E93d845A13E4d0 -pubkeyFromContract 0x046db7b0736408e7874b746f6d54aa6e4d04fd8902b520af69493f62757e77e0b5247355f925af2b382b64c71fcb3ff3ad26469ca65b4d2945d6e6379a4f285b93 -ethAddressOfPKP 0xCFcf34ED9b3A5EaCCa536a8C67E93d845A13E4d0 - ✓ checks the PKP eth address and the reverse mapping + register a PKP and set routing permissions + when the PKP is minted, check the ETH address + ✓ checks the PKP eth address and the reverse mapping + ✓ gets and sets root keys RateLimitNFT Test free minting of Rate Limit NFT +DiamondCutFacet deployed: 0x2ca60d89144D4cdf85dA87af4FE12aBF9265F28C +DiamondLoupeFacetNoERC165 deployed: 0xf4fa0d1C10c47cDe9F65D56c3eC977CbEb13449A +OwnershipFacet deployed: 0xA343B1FC2897b8C49A72A9A0B2675cB9c7664e8c +RateLimitNFTFacet deployed: 0x88B9Ad010A699Cc0c8C5C5EA8bAF90A0C375df1a ✓ checks the signature for a free mint Test minting costs and params of Rate Limit NFT +DiamondCutFacet deployed: 0x2fe19128A8257182fdD77f90eA96D27cA342897A +DiamondLoupeFacetNoERC165 deployed: 0x2f6f107D4Afd43c451B74DA41A6DDA53D2Bf24B1 +OwnershipFacet deployed: 0xb9b0c96e4E7181926D2A7ed331C9C346dfa59b4D +RateLimitNFTFacet deployed: 0x905Ad472d7eeB94ed1Fc29D8ff4B53FD4D5a5Eb4 ✓ mints a rate limit increase nft and checks the params +DiamondCutFacet deployed: 0xeF66010868Ff77119171628B7eFa0F6179779375 +DiamondLoupeFacetNoERC165 deployed: 0xd544d7A5EF50c510f3E90863828EAba7E392907A +OwnershipFacet deployed: 0x103416cfCD0D0a32b904Ab4fb69dF6E5B5aaDf2b +RateLimitNFTFacet deployed: 0x1F585372F116E1055AF2bED81a808DDf9638dCCD ✓ tries to mint with some bad params - SoloNetPKP - Attempt to Mint PKP NFT - ✓ refuses to mint for free - ✓ refuses to mint because the user is not the permittedMinter -getting token uri -got pubkey, getting eth address -calling tokenURI - ✓ mints successfully - Test free minting of PKP NFT - ✓ refuses to mint with an empty sig -sig 0x139afc97cc809f53a8275d46763bf7898a529f19d0f5d57b3d037f38e734cd816bc999e1681859c21e96737de62ac2d552e56f3a475296ecb0db7aac2504949f1c -r: 0x139afc97cc809f53a8275d46763bf7898a529f19d0f5d57b3d037f38e734cd81 -s: 0x6bc999e1681859c21e96737de62ac2d552e56f3a475296ecb0db7aac2504949f -v: 0x1c - ✓ checks the signature for a free mint - Test Mint Grant And Burn - ✓ mints, grants, and burns successfully - - SoloNetPKPHelper - Attempt to Mint PKP NFT via PKPHelper - ✓ mints successfully with permitted auth methods - ✓ mints successfully with permitted auth methods using the simple non-typed function - ✓ mints successfully with permitted auth methods and sends the PKP to itself - ✓ mints without setting the pkp nft address as permitted - ✓ mints successfully with empty auth methods - Staking -deployer has 9999609574518624661623 eth. Funding stakers... +DiamondCutFacet deployed: 0xCaC60200c1Cb424f2C1e438c7Ee1B98d487f0254 +DiamondLoupeFacet deployed: 0xABc84968376556B5e5B3C3bda750D091a06De536 +OwnershipFacet deployed: 0xFf8FA9381caf61cB3368a6ec0b3F5C788028D0Cd +StakingBalancesFacet deployed: 0xE55cc27460B55c8aC7E73043F38b537758C9E51e +DiamondCutFacet deployed: 0x3358F984e9B3CBBe976eEFE9B6fb92a214162932 +DiamondLoupeFacet deployed: 0x3Aa338c8d5E6cefE95831cD0322b558677abA0f1 +OwnershipFacet deployed: 0x6858dF5365ffCbe31b5FE68D9E6ebB81321F7F86 +StakingFacet deployed: 0x267fB71b280FB34B278CedE84180a9A9037C941b +StakingViewsFacet deployed: 0x7E27bCbe2F0eDdA3E0AA12492950a6B8703b00FB +StakingVersionFacet deployed: 0x9015957A2210BB8B10e27d8BBEEF8d9498f123eF +DiamondCutFacet deployed: 0x02121128f1Ed0AdA5Df3a87f42752fcE4Ad63e59 +DiamondLoupeFacetNoERC165 deployed: 0x95D7fF1684a8F2e202097F28Dc2e56F773A55D02 +OwnershipFacet deployed: 0x897945A56464616a525C9e5F11a8D400a72a8f3A +PKPNFTFacet deployed: 0x633a7eB9b8912b22f3616013F3153de687F96074 +deployer has 9998748505099133222081 eth. Funding stakers... ✓ can join as a staker + ✓ cannot leave as a staker if below min validator count Constructor & Settings - ✓ should staking token on constructor ✓ should set owner on constructor validators and joining ✓ has the default validator set + ✓ works with all the batch validator retrieval methods ✓ cannot stake 0 ✓ cannot stake less than the minimum stake setting new validators ✓ becomes a validator - ✓ votes to register a PKP ✓ leaves as a validator ✓ kicks and slashes validator setting new resolver contract address ✓ sets the new contract address + Alias tests + ✓ Can use an alias + Version tests + ✓ Can get min and max version + ✓ Can set min and max version only the admin can call admin functions ✓ tries to call the admin functions as a non admin and fails the admin can pause ✓ tries to pause then unpause as admin + when paused + can call mutative functions + ✓ cannot lock validators for next epoch + ✓ cannot signal ready for next epoch + ✓ cannot unlock validators for next epoch + ✓ cannot advance epoch + ✓ new stakers can stake and join + ✓ cannot exit for a reason unrelated to paused state + ✓ can request to leave + ✓ can kick validator in next epoch -·------------------------------------------------------------------|----------------------------|-------------|-----------------------------· -| Solc version: 0.8.17 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │ -···································································|····························|·············|······························ -| Methods │ -····························|······································|··············|·············|·············|···············|·············· -| Contract · Method · Min · Max · Avg · # calls · eur (avg) │ -····························|······································|··············|·············|·············|···············|·············· -| AccessControlConditions · setSigner · 29229 · 29241 · 29239 · 5 · - │ -····························|······································|··············|·············|·············|···············|·············· -| AccessControlConditions · storeCondition · 49030 · 117512 · 100386 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| AccessControlConditions · storeConditionWithSigner · 120225 · 120237 · 120228 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Allowlist · addAdmin · - · - · 75201 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Allowlist · setAllowed · - · - · 47742 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Allowlist · setNotAllowed · - · - · 25864 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · approve · - · - · 46956 · 12 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · burn · - · - · 58751 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · grantRole · - · - · 52073 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · mint · 120137 · 120233 · 120169 · 3 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · pause · - · - · 47342 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · transfer · 37820 · 54920 · 53232 · 13 · - │ -····························|······································|··············|·············|·············|···············|·············· -| LITToken · unpause · - · - · 25528 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPHelper · mintNextAndAddAuthMethods · - · - · 1764611 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPHelper · mintNextAndAddAuthMethodsWithTypes · 219053 · 1672509 · 992958 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · burn · - · - · 51612 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · freeMintNext · - · - · 190317 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · mintGrantAndBurnNext · - · - · 341504 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · mintNext · 164420 · 167220 · 164887 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · setFreeMintSigner · - · - · 30523 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · setPkpNftMetadataAddress · - · - · 47634 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · setPkpPermissionsAddress · - · - · 47547 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPNFT · setRouterAddress · - · - · 47547 · 14 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAction · 184650 · 263954 · 237515 · 3 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAddress · 178954 · 218754 · 198854 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAuthMethod · 223996 · 254114 · 239055 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAuthMethodScope · - · - · 41066 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAction · 54404 · 54414 · 54409 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAddress · - · - · 53784 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAuthMethod · - · - · 54128 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAuthMethodScope · - · - · 41135 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PKPPermissions · setRootHash · 38548 · 55648 · 47098 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PubkeyRouter · setRoutingData · 173049 · 218840 · 206134 · 9 · - │ -····························|······································|··············|·············|·············|···············|·············· -| PubkeyRouter · voteForRoutingData · 84088 · 441827 · 210275 · 14 · - │ -····························|······································|··············|·············|·············|···············|·············· -| RateLimitNFT · mint · - · - · 212133 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| RateLimitNFT · setFreeMintSigner · - · - · 47579 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · addPermittedMinter · - · - · 75290 · 11 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · freeMint · - · - · 291821 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · mint · - · - · 262153 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · mintGrantAndBurn · - · - · 417264 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · setFreeMintSigner · - · - · 30501 · 2 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · setPkpNftMetadataAddress · - · - · 47546 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · setPkpPermissionsAddress · 47513 · 47525 · 47523 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKP · setStakingAddress · - · - · 47633 · 6 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKPHelper · mintAndAddAuthMethods · - · - · 1860413 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| SoloNetPKPHelper · mintAndAddAuthMethodsWithTypes · 308019 · 1768217 · 1086928 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · advanceEpoch · 300823 · 559621 · 422510 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · exit · - · - · 58084 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · kickValidatorInNextEpoch · 65415 · 196035 · 83700 · 9 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · lockValidatorsForNextEpoch · - · - · 30295 · 4 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · pauseEpoch · - · - · 28031 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · requestToLeave · - · - · 36980 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · setEpochLength · - · - · 30266 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · setEpochState · - · - · 28379 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · setResolverContractAddress · - · - · 47673 · 1 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · signalReadyForNextEpoch · 100542 · 115518 · 106827 · 39 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Staking · stakeAndJoin · 251641 · 307753 · 260673 · 11 · - │ -····························|······································|··············|·············|·············|···············|·············· -| Deployments · · % of limit · │ -···································································|··············|·············|·············|···············|·············· -| AccessControlConditions · - · - · 1146748 · 3.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| Allowlist · - · - · 842530 · 2.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| LITToken · - · - · 4650550 · 15.5 % · - │ -···································································|··············|·············|·············|···············|·············· -| PKPHelper · - · - · 2034721 · 6.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| PKPNFT · - · - · 4926744 · 16.4 % · - │ -···································································|··············|·············|·············|···············|·············· -| PKPNFTMetadata · - · - · 1368396 · 4.6 % · - │ -···································································|··············|·············|·············|···············|·············· -| PKPPermissions · 4436144 · 4436156 · 4436156 · 14.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| PubkeyRouter · - · - · 2253040 · 7.5 % · - │ -···································································|··············|·············|·············|···············|·············· -| RateLimitNFT · - · - · 4750164 · 15.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| SoloNetPKP · - · - · 5208278 · 17.4 % · - │ -···································································|··············|·············|·············|···············|·············· -| SoloNetPKPHelper · 2054128 · 2054140 · 2054138 · 6.8 % · - │ -···································································|··············|·············|·············|···············|·············· -| Staking · - · - · 5048123 · 16.8 % · - │ -·------------------------------------------------------------------|--------------|-------------|-------------|---------------|-------------· +·---------------------------------------------------------------|----------------------------|-------------|-----------------------------· +| Solc version: 0.8.17 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │ +································································|····························|·············|······························ +| Methods │ +·························|······································|··············|·············|·············|···············|·············· +| Contract · Method · Min · Max · Avg · # calls · eur (avg) │ +·························|······································|··············|·············|·············|···············|·············· +| Allowlist · addAdmin · - · - · 75245 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| Allowlist · setAllowed · - · - · 47764 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| Allowlist · setNotAllowed · - · - · 25886 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ContractResolver · removeAllowedEnv · - · - · 25654 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ContractResolver · renounceRole · - · - · 25497 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ContractResolver · setContract · 32063 · 51975 · 51054 · 173 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletOracle · registerDomain · - · - · 344740 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletOracle · setAdmin · - · - · 27158 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · hasExpired · - · - · 46330 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · registerDomain · - · - · 538438 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · registerDomainAndMintNext · 1227179 · 1227203 · 1227199 · 13 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · removeDomain · - · - · 157693 · 4 · - │ +·························|······································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · setAdmin · - · - · 24796 · 8 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · approve · - · - · 46956 · 14 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · burn · 52489 · 62714 · 57602 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · grantRole · - · - · 52051 · 6 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · mint · 124694 · 124790 · 124726 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · pause · - · - · 47431 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · transfer · 42107 · 59207 · 57742 · 15 · - │ +·························|······································|··············|·············|·············|···············|·············· +| LITToken · unpause · - · - · 25506 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPHelper · mintNextAndAddAuthMethods · - · - · 2105481 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPHelper · mintNextAndAddAuthMethodsWithTypes · 496826 · 2015517 · 1306388 · 12 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPHelper · setContractResolver · - · - · 35689 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPNFTFacet · claimAndMint · - · - · 450855 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPNFTFacet · mintGrantAndBurnNext · - · - · 587251 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPNFTFacet · mintNext · - · - · 417890 · 9 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPNFTFacet · setFreeMintSigner · - · - · 52698 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · addPermittedAction · 73874 · 282268 · 186373 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · addPermittedAddress · 180119 · 237019 · 208569 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · addPermittedAuthMethod · 242705 · 272567 · 257636 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · addPermittedAuthMethodScope · 59509 · 59557 · 59533 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · batchAddRemoveAuthMethods · 282505 · 284272 · 283389 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · removePermittedAction · - · - · 69172 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · removePermittedAddress · - · - · 68520 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · removePermittedAuthMethod · - · - · 68878 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · removePermittedAuthMethodScope · 59489 · 59537 · 59513 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · setRootHash · 56884 · 73984 · 65434 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| PubkeyRouterFacet · voteForRootKeys · 397919 · 1575606 · 847481 · 3 · - │ +·························|······································|··············|·············|·············|···············|·············· +| RateLimitNFTFacet · mint · - · - · 218395 · 4 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · addAllowedAdminSigningPublicKey · - · - · 51372 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · addAllowedEnv · - · - · 47592 · 6 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · addAllowedSubnet · - · - · 47890 · 21 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · burnRelease · - · - · 79965 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · createRelease · 357444 · 461078 · 395563 · 49 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · grantRole · 52016 · 52028 · 52024 · 31 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · initCreator · 127264 · 127420 · 127342 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · removeAllowedAdminSigningPublicKey · - · - · 29511 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · removeAllowedEnv · - · - · 25654 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · removeAllowedSubnet · - · - · 25921 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| ReleaseRegister · setReleaseStatus · 70975 · 160981 · 115978 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingBalancesFacet · addAlias · - · - · 75918 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingBalancesFacet · addPermittedStaker · - · - · 52791 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingBalancesFacet · setPermittedStakersOn · 30474 · 52386 · 41430 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · advanceEpoch · 556267 · 785304 · 630334 · 4 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · exit · - · - · 160584 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · kickValidatorInNextEpoch · 69262 · 248886 · 102023 · 10 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · lockValidatorsForNextEpoch · - · - · 40404 · 4 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · requestToJoin · - · - · 242317 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · requestToLeave · 53025 · 63054 · 58040 · 2 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · setConfig · - · - · 55566 · 4 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · setEpochLength · - · - · 32542 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · setEpochState · 35430 · 35442 · 35436 · 19 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · signalReadyForNextEpoch · 118525 · 163922 · 133301 · 40 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingFacet · stakeAndJoin · 341624 · 393600 · 346305 · 13 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingVersionFacet · setMaxVersion · - · - · 79362 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| StakingVersionFacet · setMinVersion · - · - · 96406 · 1 · - │ +·························|······································|··············|·············|·············|···············|·············· +| Deployments · · % of limit · │ +································································|··············|·············|·············|···············|·············· +| Allowlist · - · - · 898001 · 3 % · - │ +································································|··············|·············|·············|···············|·············· +| ContractResolver · - · - · 1703781 · 5.7 % · - │ +································································|··············|·············|·············|···············|·············· +| DevKeyDeriver · - · - · 350740 · 1.2 % · - │ +································································|··············|·············|·············|···············|·············· +| DiamondCutFacet · - · - · 1615922 · 5.4 % · - │ +································································|··············|·············|·············|···············|·············· +| DiamondInit · - · - · 210098 · 0.7 % · - │ +································································|··············|·············|·············|···············|·············· +| DiamondLoupeFacet · - · - · 1023071 · 3.4 % · - │ +································································|··············|·············|·············|···············|·············· +| DiamondLoupeFacetNoERC165 · - · - · 973188 · 3.2 % · - │ +································································|··············|·············|·············|···············|·············· +| DomainWalletOracle · 3212862 · 3212874 · 3212873 · 10.7 % · - │ +································································|··············|·············|·············|···············|·············· +| DomainWalletRegistry · 3414041 · 3414053 · 3414052 · 11.4 % · - │ +································································|··············|·············|·············|···············|·············· +| LITToken · - · - · 5299565 · 17.7 % · - │ +································································|··············|·············|·············|···············|·············· +| OwnershipFacet · - · - · 257158 · 0.9 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPHelper · 4820503 · 4820515 · 4820513 · 16.1 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPNFT · 3011250 · 3011274 · 3011266 · 10 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPNFTFacet · - · - · 5095550 · 17 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPNFTMetadata · 2987679 · 2987691 · 2987689 · 10 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPPermissions · 2745890 · 2745914 · 2745908 · 9.2 % · - │ +································································|··············|·············|·············|···············|·············· +| PKPPermissionsFacet · - · - · 4850183 · 16.2 % · - │ +································································|··············|·············|·············|···············|·············· +| PubkeyRouter · 2377197 · 2377245 · 2377237 · 7.9 % · - │ +································································|··············|·············|·············|···············|·············· +| PubkeyRouterFacet · - · - · 3284916 · 10.9 % · - │ +································································|··············|·············|·············|···············|·············· +| RateLimitNFT · - · - · 3105540 · 10.4 % · - │ +································································|··············|·············|·············|···············|·············· +| RateLimitNFTFacet · - · - · 5249497 · 17.5 % · - │ +································································|··············|·············|·············|···············|·············· +| ReleaseRegister · 4483682 · 4483694 · 4483684 · 14.9 % · - │ +································································|··············|·············|·············|···············|·············· +| Staking · - · - · 3892568 · 13 % · - │ +································································|··············|·············|·············|···············|·············· +| StakingBalances · - · - · 2836612 · 9.5 % · - │ +································································|··············|·············|·············|···············|·············· +| StakingBalancesFacet · - · - · 3250823 · 10.8 % · - │ +································································|··············|·············|·············|···············|·············· +| StakingFacet · - · - · 4241115 · 14.1 % · - │ +································································|··············|·············|·············|···············|·············· +| StakingVersionFacet · - · - · 722851 · 2.4 % · - │ +································································|··············|·············|·············|···············|·············· +| StakingViewsFacet · - · - · 2052753 · 6.8 % · - │ +·---------------------------------------------------------------|--------------|-------------|-------------|---------------|-------------· - 64 passing (14s) + 99 passing (3m) +Nothing to compile + ·-----------------------------|--------------------------------|--------------------------------· + | Solc version: 0.8.17 · Optimizer enabled: false · Runs: 200 │ + ······························|································|································· + | Contract Name · Deployed size (KiB) (change) · Initcode size (KiB) (change) │ + ······························|································|································· + | console · 0.084 () · 0.162 () │ + ······························|································|································· + | LibDiamond · 0.084 () · 0.162 () │ + ······························|································|································· + | BytesLib · 0.084 () · 0.162 () │ + ······························|································|································· + | Base64 · 0.084 () · 0.162 () │ + ······························|································|································· + | Counters · 0.084 () · 0.162 () │ + ······························|································|································· + | ShortStrings · 0.084 () · 0.162 () │ + ······························|································|································· + | StorageSlot · 0.084 () · 0.162 () │ + ······························|································|································· + | Strings · 0.084 () · 0.162 () │ + ······························|································|································· + | LibPKPPermissionsStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | LibPubkeyRouterStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | LibRateLimitNFTStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | LibPKPNFTStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | LibStakingStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | LibStakingBalancesStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | ReentrancyGuardStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | AddressUpgradeable · 0.084 () · 0.162 () │ + ······························|································|································· + | StringsUpgradeable · 0.084 () · 0.162 () │ + ······························|································|································· + | ECDSA · 0.084 () · 0.162 () │ + ······························|································|································· + | MerkleProof · 0.084 () · 0.162 () │ + ······························|································|································· + | Math · 0.084 () · 0.162 () │ + ······························|································|································· + | SafeCast · 0.084 () · 0.162 () │ + ······························|································|································· + | BitMaps · 0.084 () · 0.162 () │ + ······························|································|································· + | EnumerableSet · 0.084 () · 0.162 () │ + ······························|································|································· + | ERC721Storage · 0.084 () · 0.162 () │ + ······························|································|································· + | InitializableStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | MathUpgradeable · 0.084 () · 0.162 () │ + ······························|································|································· + | SignedMathUpgradeable · 0.084 () · 0.162 () │ + ······························|································|································· + | SignedMath · 0.084 () · 0.162 () │ + ······························|································|································· + | ERC721EnumerableStorage · 0.084 () · 0.162 () │ + ······························|································|································· + | DiamondInit · 0.715 () · 0.746 () │ + ······························|································|································· + | OwnershipFacet · 0.924 () · 0.955 () │ + ······························|································|································· + | DevKeyDeriver · 1.348 () · 1.379 () │ + ······························|································|································· + | DiamondMultiInit · 2.002 () · 2.033 () │ + ······························|································|································· + | KeyDeriver · 2.581 () · 2.612 () │ + ······························|································|································· + | Multisender · 2.993 () · 3.256 () │ + ······························|································|································· + | StakingVersionFacet · 3.039 () · 3.070 () │ + ······························|································|································· + | Allowlist · 3.291 () · 3.787 () │ + ······························|································|································· + | WLIT · 3.759 () · 4.809 () │ + ······························|································|································· + | DiamondLoupeFacetNoERC165 · 4.167 () · 4.198 () │ + ······························|································|································· + | DiamondLoupeFacet · 4.393 () · 4.424 () │ + ······························|································|································· + | ERC20 · 4.546 () · 5.980 () │ + ······························|································|································· + | PKPNFT · 6.207 () · 14.134 () │ + ······························|································|································· + | RateLimitNFT · 6.207 () · 14.137 () │ + ······························|································|································· + | StakingBalances · 6.207 () · 14.133 () │ + ······························|································|································· + | PKPPermissions · 6.220 () · 14.028 () │ + ······························|································|································· + | PubkeyRouter · 6.220 () · 14.028 () │ + ······························|································|································· + | Staking · 6.220 () · 14.980 () │ + ······························|································|································· + | ContractResolver · 7.092 () · 8.146 () │ + ······························|································|································· + | DiamondCutFacet · 7.098 () · 7.129 () │ + ······························|································|································· + | ERC721Upgradeable · 8.431 () · 8.462 () │ + ······························|································|································· + | StakingViewsFacet · 9.052 () · 9.083 () │ + ······························|································|································· + | PKPNFTMetadata · 13.179 () · 13.621 () │ + ······························|································|································· + | DomainWalletOracle · 13.919 () · 14.904 () │ + ······························|································|································· + | StakingBalancesFacet · 14.509 () · 14.540 () │ + ······························|································|································· + | PubkeyRouterFacet · 14.661 () · 14.692 () │ + ······························|································|································· + | DomainWalletRegistry · 14.732 () · 15.843 () │ + ······························|································|································· + | StakingFacet · 18.992 () · 19.023 () │ + ······························|································|································· + | ReleaseRegister · 19.238 () · 20.613 () │ + ······························|································|································· + | PKPHelper · 21.353 () · 22.025 () │ + ······························|································|································· + | PKPPermissionsFacet · 21.725 () · 21.757 () │ + ······························|································|································· + | LITToken · 22.715 () · 26.154 () │ + ······························|································|································· + | PKPNFTFacet · 22.883 () · 22.915 () │ + ······························|································|································· + | RateLimitNFTFacet · 23.596 () · 23.628 () │ + ·-----------------------------|--------------------------------|--------------------------------· \ No newline at end of file diff --git a/gas_costs_before_adding_scopes.txt b/gas_costs_before_adding_scopes.txt deleted file mode 100644 index 17e9ee2..0000000 --- a/gas_costs_before_adding_scopes.txt +++ /dev/null @@ -1,172 +0,0 @@ -Compiled 4 Solidity files successfully - - AccessControlConditions - storeAndRetrieveCondition - when unauthorized - ✓ retrieves empty condition - when key is correct and condition is not permanent - ✓ retrieves condition and updates it - when key is correct and condition is permanent - ✓ retrieves condition and attempts to update it - - LITToken - ✓ grants the admin role to the deployer - ✓ grants the minter role to the deployer - mint - when unauthorized - ✓ reverts - when authorized - ✓ mints tokens - - PKPHelper - Attempt to Mint PKP NFT via PKPHelper - ✓ mints successfully with permitted auth methods - ✓ mints successfully with permitted auth methods and sends the PKP to itself - ✓ mints without setting the pkp nft address as permitted - ✓ mints successfully with empty auth methods - - PKPNFT - Attempt to Mint PKP NFT - ✓ refuses to mint for free - ✓ refuses to mint because the PKP isnt routed yet - ✓ mints successfully - Test free minting of PKP NFT - ✓ refuses to mint with an empty sig -sig 0xd113af41829b899c93ed40b7831e1e1e316b5e964ec02208a330c46262489f745c079018845714da25c8172aaf5c53b33b06ef723114bab9783e2d6991d788a11c -r: 0xd113af41829b899c93ed40b7831e1e1e316b5e964ec02208a330c46262489f74 -s: 0x5c079018845714da25c8172aaf5c53b33b06ef723114bab9783e2d6991d788a1 -v: 0x1c - ✓ checks the signature for a free mint - Test Mint Grant And Burn - ✓ mints, grants, and burns successfully - - PKPPermissions - register a PKP and set routing permissions - when the PKP grants permission to an ETH address - ✓ grants permission to an eth address and then revokes it - ✓ grants permission to an IPFS id and then revokes it - ✓ grants permission to an IPFS id and then revokes it - ✓ registers and grants permission to a generic AuthMethod - - PubkeyRouter - store and retrieve routing data - when routing data is unset - ✓ retrieves empty routing data - when routing data is set - ✓ sets and retrieves routing data - register a PKP and set routing permissions - when the PKP is minted, check the ETH address -fakePubkey 0x046db7b0736408e7874b746f6d54aa6e4d04fd8902b520af69493f62757e77e0b5247355f925af2b382b64c71fcb3ff3ad26469ca65b4d2945d6e6379a4f285b93 -ethersResult 0xCFcf34ED9b3A5EaCCa536a8C67E93d845A13E4d0 -pubkeyFromContract 0x046db7b0736408e7874b746f6d54aa6e4d04fd8902b520af69493f62757e77e0b5247355f925af2b382b64c71fcb3ff3ad26469ca65b4d2945d6e6379a4f285b93 -ethAddressOfPKP 0xCFcf34ED9b3A5EaCCa536a8C67E93d845A13E4d0 - ✓ checks the PKP eth address and the reverse mapping - - RateLimitNFT - Attempt to Mint Rate Limit NFT - ✓ refuses to mint for free - Test free minting of Rate Limit NFT - ✓ checks the signature for a free mint - - Staking -deployer has 9999811648664705650241 eth. Funding stakers... - ✓ can join as a staker - Constructor & Settings - ✓ should staking token on constructor - ✓ should set owner on constructor - validators and joining - ✓ has the default validator set - ✓ cannot stake 0 - ✓ cannot stake less than the minimum stake - setting new validators - ✓ becomes a validator - ✓ votes to register a PKP - ✓ leaves as a validator - ✓ kicks and slashes validator - -·----------------------------------------------------------|----------------------------|-------------|-----------------------------· -| Solc version: 0.8.7 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │ -···························································|····························|·············|······························ -| Methods │ -····························|······························|··············|·············|·············|···············|·············· -| Contract · Method · Min · Max · Avg · # calls · eur (avg) │ -····························|······························|··············|·············|·············|···············|·············· -| AccessControlConditions · storeCondition · 41380 · 94933 · 81539 · 4 · - │ -····························|······························|··············|·············|·············|···············|·············· -| LITToken · approve · - · - · 46879 · 12 · - │ -····························|······························|··············|·············|·············|···············|·············· -| LITToken · grantRole · - · - · 52028 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| LITToken · mint · 71548 · 71572 · 71560 · 2 · - │ -····························|······························|··············|·············|·············|···············|·············· -| LITToken · transfer · 35211 · 52311 · 50886 · 12 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPHelper · mintNextAndAddAuthMethods · 237653 · 1173598 · 723558 · 4 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · freeMintNext · - · - · 192880 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · mintGrantAndBurnNext · - · - · 282580 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · mintNext · 184742 · 186895 · 186464 · 5 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · setFreeMintSigner · - · - · 29362 · 2 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · setPkpPermissionsAddress · - · - · 46386 · 6 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPNFT · setRouterAddress · 46374 · 46386 · 46385 · 13 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAction · 108222 · 167948 · 148035 · 3 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAddress · - · - · 99913 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · addPermittedAuthMethod · - · - · 237147 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAction · 39976 · 39985 · 39981 · 2 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAddress · - · - · 39161 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PKPPermissions · removePermittedAuthMethod · - · - · 53344 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PubkeyRouter · setRoutingData · 171403 · 217105 · 199964 · 8 · - │ -····························|······························|··············|·············|·············|···············|·············· -| PubkeyRouter · voteForRoutingData · 84404 · 440307 · 193268 · 13 · - │ -····························|······························|··············|·············|·············|···············|·············· -| RateLimitNFT · setFreeMintSigner · - · - · 46396 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · advanceEpoch · 287614 · 563783 · 412798 · 4 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · exit · - · - · 56865 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · kickValidatorInNextEpoch · 63326 · 159354 · 77744 · 9 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · lockValidatorsForNextEpoch · - · - · 30295 · 4 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · requestToLeave · - · - · 37004 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · setEpochLength · - · - · 29075 · 1 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · signalReadyForNextEpoch · 102349 · 117758 · 108925 · 39 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Staking · stakeAndJoin · 250681 · 306793 · 259722 · 11 · - │ -····························|······························|··············|·············|·············|···············|·············· -| Deployments · · % of limit · │ -···························································|··············|·············|·············|···············|·············· -| AccessControlConditions · - · - · 620305 · 2.1 % · - │ -···························································|··············|·············|·············|···············|·············· -| LITToken · - · - · 2320985 · 7.7 % · - │ -···························································|··············|·············|·············|···············|·············· -| PKPHelper · 1465995 · 1466007 · 1466001 · 4.9 % · - │ -···························································|··············|·············|·············|···············|·············· -| PKPNFT · - · - · 5225069 · 17.4 % · - │ -···························································|··············|·············|·············|···············|·············· -| PKPPermissions · 3174503 · 3174515 · 3174513 · 10.6 % · - │ -···························································|··············|·············|·············|···············|·············· -| PubkeyRouter · 2163402 · 2163414 · 2163413 · 7.2 % · - │ -···························································|··············|·············|·············|···············|·············· -| RateLimitNFT · - · - · 4729957 · 15.8 % · - │ -···························································|··············|·············|·············|···············|·············· -| Staking · 4656263 · 4656275 · 4656275 · 15.5 % · - │ -·----------------------------------------------------------|--------------|-------------|-------------|---------------|-------------· - - 36 passing (10s) - diff --git a/hardhat.config.js b/hardhat.config.js deleted file mode 100644 index 6b57767..0000000 --- a/hardhat.config.js +++ /dev/null @@ -1,188 +0,0 @@ -require("@nomiclabs/hardhat-waffle"); -// require('hardhat-ethernal'); // required for ethernal - removing this will only break deploy scripts that are linked to ethernal . -// Commenting out lines in these deploy scripts doesn't break the deploy, only the synchronization with Ethernal - ie, safe to do. -// Tests & regular deploys continue to work normally. -// Ethernal is a web based block explorer that syncs from any EVM chain - easy way to "view" hardhat data, and execute contracts! -// https://www.tryethernal.com - -require("@nomiclabs/hardhat-etherscan"); - -require("@tenderly/hardhat-tenderly"); - -require("hardhat-gas-reporter"); - -// This is a sample Hardhat task. To learn how to create your own go to -// https://hardhat.org/guides/create-task.html -task("accounts", "Prints the list of accounts", async () => { - const accounts = await ethers.getSigners(); - - for (const account of accounts) { - console.log(account.address); - } -}); - -// You need to export an object to set up your config -// Go to https://hardhat.org/config/ to learn more - -function envVarOrDefault(envVar, defaultValue) { - if (process.env[envVar] == undefined) { - return defaultValue; - } - return process.env[envVar]; -} - -// NOTE, below we use the privkey key 0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166 -// as a default. it is empty. DO NOT SEND MONEY TO IT. it's public. - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - version: "0.8.17", - settings: { - outputSelection: { - "*": { - "*": ["storageLayout"], - }, - }, - optimizer: { - enabled: false, - runs: 200, - }, - }, - }, - networks: { - celo: { - url: "https://forno.celo.org", - accounts: [ - envVarOrDefault( - "LIT_CELO_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - }, - mumbai: { - url: "https://polygon-mumbai.g.alchemy.com/v2/onvoLvV97DDoLkAmdi0Cj7sxvfglKqDh", - accounts: [ - envVarOrDefault( - "LIT_MUMBAI_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - }, - alfajores: { - url: "https://alfajores-forno.celo-testnet.org", - accounts: [ - envVarOrDefault( - "LIT_ALFAJORES_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - }, - polygon: { - url: "https://polygon-rpc.com", - accounts: [ - envVarOrDefault( - "LIT_POLYGON_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - }, - litTestnet: { - url: "https://lit-test.calderachain.xyz/http", - accounts: [ - envVarOrDefault( - "LIT_ROLLUP_TESTNET_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - chainId: 987, - }, - lit: { - url: "https://lit-protocol.calderachain.xyz/http", - accounts: [ - envVarOrDefault( - "LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY", - "0x3178746f7ae6a309d14444b4c6c85a96a4be2f53fa8950dea241d232f3e6c166" - ), - ], - chainId: 175177, - wlitAddress: "0x53695556f8a1a064EdFf91767f15652BbfaFaD04", - }, - localchain: { - url: "http://127.0.0.1:8545", - accounts: [ - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", // default anvil private key, - ], - chainId: 31337, - wlitAddress: "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", // this gets deployed by deploy_everything.js but because it's deterministic we know it will end up at this address. but only if you start anvil fresh for the deploy! - }, - }, - etherscan: { - apiKey: { - celo: process.env.LIT_CELOSCAN_API_KEY, - mumbai: process.env.LIT_POLYGONSCAN_API_KEY, - polygon: process.env.LIT_POLYGONSCAN_API_KEY, - litTestnet: "meow", - lit: "woof", - }, - customChains: [ - { - network: "celo", - chainId: 42220, - urls: { - apiURL: "https://api.celoscan.io/api", - browserURL: "https://celoscan.io", - }, - }, - { - network: "alfajores", - chainId: 44787, - urls: { - apiURL: "https://api-alfajores.celoscan.io/api", - browserURL: "https://alfajores.celoscan.io/", - }, - }, - { - network: "mumbai", - chainId: 80001, - urls: { - apiURL: "https://api-testnet.polygonscan.com/api", - browserURL: "https://mumbai.polygonscan.com", - }, - }, - { - network: "polygon", - chainId: 137, - urls: { - apiURL: "https://api.polygonscan.com/api", - browserURL: "https://polygonscan.com", - }, - }, - { - network: "litTestnet", - chainId: 987, - urls: { - apiURL: "https://lit-test.calderaexplorer.xyz/api", - browserURL: "https://lit-test.calderaexplorer.xyz", - }, - }, - { - network: "lit", - chainId: 175177, - urls: { - apiURL: "https://lit-protocol.calderaexplorer.xyz/api", - browserURL: "https://lit-protocol.calderaexplorer.xyz", - }, - }, - ], - }, - tenderly: { - project: "litnodecontracts", - username: "rwiggum", - // forkNetwork: "", - privateVerification: false, - // deploymentsDir: "deployments" - }, -}; diff --git a/hardhat.config.ts b/hardhat.config.ts new file mode 100644 index 0000000..a425697 --- /dev/null +++ b/hardhat.config.ts @@ -0,0 +1,382 @@ +import '@nomicfoundation/hardhat-toolbox'; +// import "hardhat-ethernal"; // required for ethernal - removing this will only break deploy scripts that are linked to ethernal . +// Commenting out lines in these deploy scripts doesn't break the deploy, only the synchronization with Ethernal - ie, safe to do. +// Tests & regular deploys continue to work normally. +// Ethernal is a web based block explorer that syncs from any EVM chain - easy way to "view" hardhat data, and execute contracts! +// https://www.tryethernal.com + +import 'hardhat-contract-sizer'; + +import '@kingdomstudios/hardhat-diamond-abi'; + +// Uncomment the below to enable the tracer. +// FIXME: There is an unresolved issue whether running the npm run deploy script with +// the tracer enabled will prevent the child process from exiting. +// Issue: https://github.com/zemse/hardhat-tracer/issues/57 +// import "hardhat-tracer"; + +import { HardhatUserConfig } from 'hardhat/types'; +// import "hardhat-tracer"; + +import { ProviderWrapper } from 'hardhat/plugins'; + +// @ts-ignore +extendProvider(async (provider, config, network: string) => { + const LIT_NETWORKS = ['lit', 'etna']; + if (LIT_NETWORKS.includes(network)) { + return new OldGethProvider(provider); + } else if ( + network === 'localchain' && + config.networks['localchain'].slowDownProvider + ) { + return new SlowerGethProvider(provider); + } + + return provider; +}); + +// This is a sample Hardhat task. To learn how to create your own go to +// https://hardhat.org/guides/create-task.html +// @ts-ignore +task('accounts', 'Prints the list of accounts', async () => { + // @ts-ignore + const accounts = await ethers.getSigners(); + + for (const account of accounts) { + console.log(account.address); + } +}); + +// You need to export an object to set up your config +// Go to https://hardhat.org/config/ to learn more + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +const config: HardhatUserConfig = { + solidity: { + version: '0.8.17', + settings: { + outputSelection: { + '*': { + '*': ['storageLayout'], + }, + }, + optimizer: { + enabled: false, + runs: 200, + }, + }, + }, + networks: { + celo: { + url: 'https://forno.celo.org', + ...(process.env['LIT_CELO_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_CELO_DEPLOYER_PRIVATE_KEY']], + }), + }, + mumbai: { + url: 'https://polygon-mumbai.g.alchemy.com/v2/onvoLvV97DDoLkAmdi0Cj7sxvfglKqDh', + ...(process.env['LIT_MUMBAI_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_MUMBAI_DEPLOYER_PRIVATE_KEY']], + }), + }, + alfajores: { + url: 'https://alfajores-forno.celo-testnet.org', + ...(process.env['LIT_ALFAJORES_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_ALFAJORES_DEPLOYER_PRIVATE_KEY']], + }), + }, + polygon: { + url: 'https://polygon-rpc.com', + ...(process.env['LIT_POLYGON_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_POLYGON_DEPLOYER_PRIVATE_KEY']], + }), + }, + litTestnet: { + url: 'https://lit-test.calderachain.xyz/http', + ...(process.env['LIT_ROLLUP_TESTNET_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_ROLLUP_TESTNET_DEPLOYER_PRIVATE_KEY']], + }), + chainId: 987, + }, + lit: { + url: 'https://lit-protocol.calderachain.xyz/http', + ...(process.env['LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY']], + }), + chainId: 175177, + // @ts-ignore + wlitAddress: '0x53695556f8a1a064EdFf91767f15652BbfaFaD04', + }, + etna: { + url: 'https://etna-testnet.rpc.caldera.xyz/http', + ...(process.env['LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_ROLLUP_MAINNET_DEPLOYER_PRIVATE_KEY']], + }), + chainId: 175178, + // @ts-ignore + wlitAddress: '0xCbb5E24a8d7d1E704cA6939c0e673569030ceeC1', + }, + localchain: { + url: 'http://127.0.0.1:8545', + accounts: [ + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', // default anvil private key, + '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', + '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a', + '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6', + '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a', + '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', + '0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e', + '0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356', + '0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', + '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', + ], + chainId: 31337, + // @ts-ignore + slowDownProvider: + (process.env['LIT_SLOW_DOWN_PROVIDER'] || 'false') === 'true', + // @ts-ignore + wlitAddress: '0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0', // this gets deployed by deploy_everything.js but because it's deterministic we know it will end up at this address. but only if you start anvil fresh for the deploy! + }, + sepolia: { + url: 'https://sepolia.infura.io/v3/ddf1ca3700f34497bca2bf03607fde38', + ...(process.env['LIT_SEPOLIA_DEPLOYER_PRIVATE_KEY'] && { + accounts: [process.env['LIT_SEPOLIA_DEPLOYER_PRIVATE_KEY']], + }), + chainId: 11155111, + }, + }, + etherscan: { + apiKey: { + celo: process.env.LIT_CELOSCAN_API_KEY!, + mumbai: process.env.LIT_POLYGONSCAN_API_KEY!, + polygon: process.env.LIT_POLYGONSCAN_API_KEY!, + litTestnet: 'meow', + lit: 'woof', + sepolia: process.env.LIT_ETHERSCAN_API_KEY!, + }, + customChains: [ + { + network: 'celo', + chainId: 42220, + urls: { + apiURL: 'https://api.celoscan.io/api', + browserURL: 'https://celoscan.io', + }, + }, + { + network: 'alfajores', + chainId: 44787, + urls: { + apiURL: 'https://api-alfajores.celoscan.io/api', + browserURL: 'https://alfajores.celoscan.io/', + }, + }, + { + network: 'mumbai', + chainId: 80001, + urls: { + apiURL: 'https://api-testnet.polygonscan.com/api', + browserURL: 'https://mumbai.polygonscan.com', + }, + }, + { + network: 'polygon', + chainId: 137, + urls: { + apiURL: 'https://api.polygonscan.com/api', + browserURL: 'https://polygonscan.com', + }, + }, + { + network: 'litTestnet', + chainId: 987, + urls: { + apiURL: 'https://lit-test.calderaexplorer.xyz/api', + browserURL: 'https://lit-test.calderaexplorer.xyz', + }, + }, + { + network: 'lit', + chainId: 175177, + urls: { + apiURL: 'https://lit-protocol.calderaexplorer.xyz/api', + browserURL: 'https://lit-protocol.calderaexplorer.xyz', + }, + }, + { + network: 'etna', + chainId: 175178, + urls: { + apiURL: 'https://etna-testnet.explorer.caldera.xyz/api', + browserURL: 'https://etna-testnet.explorer.caldera.xyz/', + }, + }, + ], + }, + tenderly: { + project: 'litnodecontracts', + username: 'rwiggum', + privateVerification: false, + }, + diamondAbi: [ + { + // (required) The name of your Diamond ABI. + name: 'StakingDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'StakingFacet', + 'StakingViewsFacet', + 'StakingVersionFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'PKPPermissionsDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'PKPPermissionsFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'PubkeyRouterDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'PubkeyRouterFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'RateLimitNFTDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'RateLimitNFTFacet', + 'RateLimitNFTViewsFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacetNoERC165', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'StakingBalancesDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'StakingBalancesFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'PKPNFTDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'PKPNFTFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacetNoERC165', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'BackupRecoveryDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'BackupRecoveryFacet', + 'BackupRecoveryTestFacet', + 'BackupRecoveryNodeStatusFacet', + 'BackupRecoveryViewFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacetNoERC165', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'DomainWalletRegistryDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'DomainWalletRegistryFacet', + 'DomainWalletRegistryViewsFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + { + // (required) The name of your Diamond ABI. + name: 'PaymentDelegationDiamond', + // (optional) An array of strings, matched against fully qualified contract names, to + // determine which contracts are included in your Diamond ABI. + include: [ + 'OwnershipFacet', + 'PaymentDelegationFacet', + 'DiamondCutFacet', + 'DiamondLoupeFacet', + ], + }, + ], + mocha: { + timeout: 60000, + }, +}; + +export default config; + +/** + * This provider implements workarounds for old geth versions that do not support: + * - An additional parameter in eth_estimateGas, so we strip it out. + */ +class OldGethProvider extends ProviderWrapper { + constructor(protected readonly _wrappedProvider: any) { + super(_wrappedProvider); + + console.info('Using OldGethProvider'); + } + + public async request(args: any) { + if (args.method === 'eth_estimateGas') { + const adjustedRequest = { + ...args, + params: args.params.slice(0, args.params.length - 1), + }; + return this._wrappedProvider.request(adjustedRequest); + } + + return this._wrappedProvider.request(args); + } +} + +class SlowerGethProvider extends ProviderWrapper { + constructor(protected readonly _wrappedProvider: any) { + super(_wrappedProvider); + + console.info('Using SlowerGethProvider'); + } + + public async request(args: any) { + await new Promise((resolve) => setTimeout(resolve, 50)); + return this._wrappedProvider.request(args); + } +} diff --git a/ipfsIdToAllowlistHash.js b/ipfsIdToAllowlistHash.js deleted file mode 100644 index 96c2735..0000000 --- a/ipfsIdToAllowlistHash.js +++ /dev/null @@ -1,8 +0,0 @@ -const { ethers } = require("ethers"); -const ipfsId = "QmRwN9GKHvCn4Vk7biqtr6adjXMs7PzzYPCzNCRjPFiDjm"; - -const converted = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes("LIT_ACTION_" + ipfsId) -); - -console.log("as bytes: ", converted); diff --git a/ipfsIdToBytes.js b/ipfsIdToBytes.js deleted file mode 100644 index 90bdf44..0000000 --- a/ipfsIdToBytes.js +++ /dev/null @@ -1,7 +0,0 @@ -const { getBytesFromMultihash } = require("./utils.js"); - -const ipfsId = "QmRwN9GKHvCn4Vk7biqtr6adjXMs7PzzYPCzNCRjPFiDjm"; - -const converted = getBytesFromMultihash(ipfsId); - -console.log("as bytes: ", converted); diff --git a/mintSoloNetPkp.sh b/mintSoloNetPkp.sh deleted file mode 100755 index 47e819f..0000000 --- a/mintSoloNetPkp.sh +++ /dev/null @@ -1,2 +0,0 @@ - -npx hardhat run --network mumbai scripts/solo_net_mint_pkp_with_helper.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d0f4518 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10970 @@ +{ + "name": "lit-assets-blockchain", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "lit-assets-blockchain", + "version": "1.0.0", + "license": "GPL-3.0-or-later", + "dependencies": { + "@gnus.ai/contracts-upgradeable-diamond": "GeniusVentures/openzeppelin-contracts-diamond", + "@iarna/toml": "^2.2.5", + "@kingdomstudios/hardhat-diamond-abi": "^2.2.0", + "@noble/ed25519": "^1.7.1", + "@openzeppelin/contracts": "^4.9.6", + "axios": "^1.6.2", + "bs58": "^5.0.0", + "dotenv": "^16.4.5", + "ethers": "^6.1.0", + "ethers-v5": "npm:ethers@5.7.1", + "hardhat-tracer": "^2.8.1", + "inquirer": "8.0.1", + "solidity-bytes-utils": "^0.8.2", + "tweetnacl": "^1.0.3", + "uint8arrays": "3", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^3.0.0", + "@openzeppelin/merkle-tree": "^1.0.1", + "@types/chai": "^4.3.4", + "@types/inquirer": "^8.1.0", + "@types/mocha": "^10.0.1", + "@types/node": "^18.15.11", + "@types/yargs": "^17.0.24", + "@wagmi/cli": "^2.1.4", + "glob": "^10.2.1", + "hardhat": "^2.20.1", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-ethernal": "^3.2.0", + "prettier": "^2.7.1", + "prettier-plugin-solidity": "^1.1.3", + "simple-git": "^3.24.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.4", + "yargs": "^17.7.1" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", + "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", + "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", + "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.3.0", + "@noble/hashes": "1.3.3", + "@scure/bip32": "1.3.3", + "@scure/bip39": "1.2.2" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.1.tgz", + "integrity": "sha512-vZveG/DLyo+wk4Ga1yx6jSEHrLPgmTt+dFv0dv8URpVCRf0jVhalps1jq/emN/oXnMRsC7cQgAF32DcXLL7BPQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.8.0.tgz", + "integrity": "sha512-wkcwainNm8Cu2xkJpDSHfhBSdDJn86Q1TZNmLWc67VrhZUHXIKXxIqb65/tNUVE+I8+sFiDDNwA+9R3MqTQTaA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/installations": "0.5.12", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.1.13.tgz", + "integrity": "sha512-QC1DH/Dwc8fBihn0H+jocBWyE17GF1fOCpCrpAiQ2u16F/NqsVDVG4LjIqdhq963DXaXneNY7oDwa25Up682AA==", + "dev": true, + "dependencies": { + "@firebase/analytics": "0.8.0", + "@firebase/analytics-types": "0.7.0", + "@firebase/component": "0.5.17", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.7.0.tgz", + "integrity": "sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ==", + "dev": true + }, + "node_modules/@firebase/app": { + "version": "0.7.32", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.32.tgz", + "integrity": "sha512-FUqDHgCkr6oVTTpastIlquYsMtkd8Tg4SR8+z4sCJ1C1pbPavazN9qeYIqHQjviqLV/OflCrACCZj/s2zlh0ww==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.5.12.tgz", + "integrity": "sha512-l+MmvupSGT/F+I5ei7XjhEfpoL4hLVJr0vUwcG5NEf2hAkQnySli9fnbl9fZu1BJaQ2kthrMmtg1gcbcM9BUCQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.2.12.tgz", + "integrity": "sha512-GFppNLlUyMN9Iq31ME/+GkjRVKlc+MeanzUKQ9UaR73ZsYH3oX3Ja+xjoYgixaVJDDG+ofBYR7ZXTkkQdSR/pw==", + "dev": true, + "dependencies": { + "@firebase/app-check": "0.5.12", + "@firebase/app-check-types": "0.4.0", + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz", + "integrity": "sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA==", + "dev": true + }, + "node_modules/@firebase/app-check-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.4.0.tgz", + "integrity": "sha512-SsWafqMABIOu7zLgWbmwvHGOeQQVQlwm42kwwubsmfLmL4Sf5uGpBfDhQ0CAkpi7bkJ/NwNFKafNDL9prRNP0Q==", + "dev": true + }, + "node_modules/@firebase/app-compat": { + "version": "0.1.33", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.33.tgz", + "integrity": "sha512-PLCwOpduJOOkw2v0ygBPpYBRobbnxJjZVaj2xjc5IPakHWx9sLHHX3KoZnl+7ZonY1xJ2lCQaLQrwqX2hi0FXg==", + "dev": true, + "dependencies": { + "@firebase/app": "0.7.32", + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==", + "dev": true, + "peer": true + }, + "node_modules/@firebase/auth": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.20.6.tgz", + "integrity": "sha512-99R3bY7aQ2zFh5BdqLEgI/qN87l3bPBLIse2eDVcSRwChaM6FTdIKoKk15L1M4ry8utatMtYFt1vRCol7QDsLg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "node-fetch": "2.6.7", + "selenium-webdriver": "4.1.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.19.tgz", + "integrity": "sha512-gB9fnPZM2mnNrGR7n6Y+xDC/4cSouDVfdwPYL7GuLv7b48iW1u24DC9Trv10gNUUGq6iGEyqgJgCSrVmlTkX7Q==", + "dev": true, + "dependencies": { + "@firebase/auth": "0.20.6", + "@firebase/auth-types": "0.11.0", + "@firebase/component": "0.5.17", + "@firebase/util": "1.6.3", + "node-fetch": "2.6.7", + "selenium-webdriver": "4.1.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth-types": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.11.0.tgz", + "integrity": "sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.17.tgz", + "integrity": "sha512-mTM5CBSIlmI+i76qU4+DhuExnWtzcPS3cVgObA3VAjliPPr3GrUlTaaa8KBGfxsD27juQxMsYA0TvCR5X+GQ3Q==", + "dev": true, + "dependencies": { + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.6.tgz", + "integrity": "sha512-5IZIBw2LT50Z8mwmKYmdX37p+Gg2HgeJsrruZmRyOSVgbfoY4Pg87n1uFx6qWqDmfL6HwQgwcrrQfVIXE3C5SA==", + "dev": true, + "dependencies": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.6.tgz", + "integrity": "sha512-Ls1BAODaiDYgeJljrIgSuC7JkFIY/HNhhNYebzZSoGQU62RuvnaO3Qgp2EH6h2LzHyRnycNadfh1suROtPaUIA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/database": "0.13.6", + "@firebase/database-types": "0.9.13", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.9.13", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.13.tgz", + "integrity": "sha512-dIJ1zGe3EHMhwcvukTOPzYlFYFIG1Et5Znl7s7y/ZTN2/toARRNnsv1qCKvqevIMYKvIrRsYOYfOXDS8l1YIJA==", + "dev": true, + "dependencies": { + "@firebase/app-types": "0.7.0", + "@firebase/util": "1.6.3" + } + }, + "node_modules/@firebase/database-types/node_modules/@firebase/app-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==", + "dev": true + }, + "node_modules/@firebase/firestore": { + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.4.15.tgz", + "integrity": "sha512-1kal1/0UC1p9x99f0iXwWbmBL/RClksdkqLSd8HVQVawAMTR3zCVKE95omNGl0egRRlDN6c/i8XBEfkwj3SHxw==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "@firebase/webchannel-wrapper": "0.6.2", + "@grpc/grpc-js": "^1.3.2", + "@grpc/proto-loader": "^0.6.13", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10.10.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.1.24.tgz", + "integrity": "sha512-wy9AerWLyg/RcbjKE9I73TyBW7FMVfxblGUbcRRHi5tSSrjp+JT1jsGriF6NjAij4byboaGVm8Hgrki7Oqf2kw==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/firestore": "3.4.15", + "@firebase/firestore-types": "2.5.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-compat/node_modules/@firebase/firestore-types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.0.tgz", + "integrity": "sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.2.0.tgz", + "integrity": "sha512-5kZZtQ32FIRJP1029dw+ZVNRCclKOErHv1+Xn0pw/5Fq3dxroA/ZyFHqDu+uV52AyWHhNLjCqX43ibm4YqOzRw==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.8.4.tgz", + "integrity": "sha512-o1bB0xMyQKe+b246zGnjwHj4R6BH4mU2ZrSaa/3QvTpahUQ3hqYfkZPLOXCU7+vEFxHb3Hd4UUjkFhxoAcPqLA==", + "dev": true, + "dependencies": { + "@firebase/app-check-interop-types": "0.1.0", + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.17", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.6.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.2.4.tgz", + "integrity": "sha512-Crfn6il1yXGuXkjSd8nKrqR4XxPvuP19g64bXpM6Ix67qOkQg676kyOuww0FF17xN0NSXHfG8Pyf+CUrx8wJ5g==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/functions": "0.8.4", + "@firebase/functions-types": "0.5.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.5.0.tgz", + "integrity": "sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA==", + "dev": true + }, + "node_modules/@firebase/installations": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.5.12.tgz", + "integrity": "sha512-Zq43fCE0PB5tGJ3ojzx5RNQzKdej1188qgAk22rwjuhP7npaG/PlJqDG1/V0ZjTLRePZ1xGrfXSPlA17c/vtNw==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/util": "1.6.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.1.12.tgz", + "integrity": "sha512-BIhFpWIn/GkuOa+jnXkp3SDJT2RLYJF6MWpinHIBKFJs7MfrgYZ3zQ1AlhobDEql+bkD1dK4dB5sNcET2T+EyA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/installations": "0.5.12", + "@firebase/installations-types": "0.4.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.4.0.tgz", + "integrity": "sha512-nXxWKQDvBGctuvsizbUEJKfxXU9WAaDhon+j0jpjIfOJkvkj3YHqlLB/HeYjpUn85Pb22BjplpTnDn4Gm9pc3A==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.3.tgz", + "integrity": "sha512-POTJl07jOKTOevLXrTvJD/VZ0M6PnJXflbAh5J9VGkmtXPXNG6MdZ9fmRgqYhXKTaDId6AQenQ262uwgpdtO0Q==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.16.tgz", + "integrity": "sha512-Yl9gGrAvJF6C1gg3+Cr2HxlL6APsDEkrorkFafmSP1l+rg1epZKoOAcKJbSF02Vtb50wfb9FqGGy8tzodgETxg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/installations": "0.5.12", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.6.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.16.tgz", + "integrity": "sha512-uG7rWcXJzU8vvlEBFpwG1ndw/GURrrmKcwsHopEWbsPGjMRaVWa7XrdKbvIR7IZohqPzcC/V9L8EeqF4Q4lz8w==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/messaging": "0.9.16", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz", + "integrity": "sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ==", + "dev": true + }, + "node_modules/@firebase/performance": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.5.12.tgz", + "integrity": "sha512-MPVTkOkGrm2SMQgI1FPNBm85y2pPqlPb6VDjIMCWkVpAr6G1IZzUT24yEMySRcIlK/Hh7/Qu1Nu5ASRzRuX6+Q==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/installations": "0.5.12", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.1.12.tgz", + "integrity": "sha512-IBORzUeGY1MGdZnsix9Mu5z4+C3WHIwalu0usxvygL0EZKHztGG8bppYPGH/b5vvg8QyHs9U+Pn1Ot2jZhffQQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/performance": "0.5.12", + "@firebase/performance-types": "0.1.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.1.0.tgz", + "integrity": "sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w==", + "dev": true + }, + "node_modules/@firebase/remote-config": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.3.11.tgz", + "integrity": "sha512-qA84dstrvVpO7rWT/sb2CLv1kjHVmz59SRFPKohJJYFBcPOGK4Pe4FWWhKAE9yg1Gnl0qYAGkahOwNawq3vE0g==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/installations": "0.5.12", + "@firebase/logger": "0.3.3", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.1.12.tgz", + "integrity": "sha512-Yz7Gtb2rLa7ykXZX9DnSTId8CXd++jFFLW3foUImrYwJEtWgLJc7gwkRfd1M73IlKGNuQAY+DpUNF0n1dLbecA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/logger": "0.3.3", + "@firebase/remote-config": "0.3.11", + "@firebase/remote-config-types": "0.2.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz", + "integrity": "sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw==", + "dev": true + }, + "node_modules/@firebase/storage": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.9.9.tgz", + "integrity": "sha512-Zch7srLT2SIh9y2nCVv/4Kne0HULn7OPkmreY70BJTUJ+g5WLRjggBq6x9fV5ls9V38iqMWfn4prxzX8yIc08A==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/util": "1.6.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.1.17.tgz", + "integrity": "sha512-nOYmnpI0gwoz5nROseMi9WbmHGf+xumfsOvdPyMZAjy0VqbDnpKIwmTUZQBdR+bLuB5oIkHQsvw9nbb1SH+PzQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.5.17", + "@firebase/storage": "0.9.9", + "@firebase/storage-types": "0.6.0", + "@firebase/util": "1.6.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.6.0.tgz", + "integrity": "sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.6.3.tgz", + "integrity": "sha512-FujteO6Zjv6v8A4HS+t7c+PjU0Kaxj+rOnka0BsI/twUaCC9t8EQPmXpWZdk7XfszfahJn2pqsflUWUhtUkRlg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.2.tgz", + "integrity": "sha512-zThUKcqIU6utWzM93uEvhlh8qj8A5LMPFJPvk/ODb+8GSSif19xM2Lw1M2ijyBy8+6skSkQBbavPzOU5Oh/8tQ==", + "dev": true + }, + "node_modules/@gnus.ai/contracts-upgradeable-diamond": { + "version": "4.9.1", + "resolved": "git+ssh://git@github.com/GeniusVentures/openzeppelin-contracts-diamond.git#5e8cb37c70ece804441f549331d361faf28e5345", + "license": "MIT", + "bin": { + "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "dev": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "dev": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/grpc-js/node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "dev": true + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dev": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@kingdomstudios/hardhat-diamond-abi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@kingdomstudios/hardhat-diamond-abi/-/hardhat-diamond-abi-2.2.0.tgz", + "integrity": "sha512-xDxNekeDjnnQVlWwjjvVCuVaQOCbhQWQEX4QVl+pSlnSZ/kFMppEEQktBEQPu5Nvhae2UA9NfB3lv82kZoIIhg==", + "dependencies": { + "debug": "^4.3.3", + "ethers": "^5.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/@kingdomstudios/hardhat-diamond-abi/node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@kingdomstudios/hardhat-diamond-abi/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/@kingdomstudios/hardhat-diamond-abi/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/ethereumjs-block": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.4.tgz", + "integrity": "sha512-AcyacJ9eX/uPEvqsPiB+WO1ymE+kyH48qGGiGV+YTojdtas8itUTW5dehDSOXEEItWGbbzEJ4PRqnQZlWaPvDw==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-trie": "6.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-block/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.4.tgz", + "integrity": "sha512-jYsd/kwzbmpnxx86tXsYV8wZ5xGvFL+7/P0c6OlzpClHsbFzeF41KrYA9scON8Rg6bZu3ZTv6JOAgj3t7USUfg==", + "dependencies": { + "@nomicfoundation/ethereumjs-block": "5.0.4", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-ethash": "3.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-trie": "6.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "lru-cache": "^10.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.4.tgz", + "integrity": "sha512-xvIrwIMl9sSaiYKRem68+O7vYdj7Q2XWv5P7JXiIkn83918QzWHvqbswTRsH7+r6X1UEvdsURRnZbvZszEjAaQ==", + "dependencies": { + "@nomicfoundation/ethereumjs-block": "5.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "bigint-crypto-utils": "^3.2.2", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.4.tgz", + "integrity": "sha512-lTyZZi1KpeMHzaO6cSVisR2tjiTTedjo7PcmhI/+GNFo9BmyY6QYzGeSti0sFttmjbEMioHgXxl5yrLNRg6+1w==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-statemanager": "2.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@types/debug": "^4.1.9", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "rustbn-wasm": "^0.2.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.4.tgz", + "integrity": "sha512-HPDjeFrxw6llEi+BzqXkZ+KkvFnTOPczuHBtk21hRlDiuKuZz32dPzlhpRsDBGV1b5JTmRDUVqCS1lp3Gghw4Q==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-trie": "6.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "js-sdsl": "^4.1.4", + "lru-cache": "^10.0.0" + }, + "peerDependencies": { + "@nomicfoundation/ethereumjs-verkle": "0.0.2" + }, + "peerDependenciesMeta": { + "@nomicfoundation/ethereumjs-verkle": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-trie": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.4.tgz", + "integrity": "sha512-3nSwQiFMvr2VFe/aZUyinuohYvtytUqZCUCvIWcPJ/BwJH6oQdZRB42aNFBJ/8nAh2s3OcroWpBLskzW01mFKA==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@types/readable-stream": "^2.3.13", + "ethereum-cryptography": "0.1.3", + "lru-cache": "^10.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-trie/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-verkle": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-verkle/-/ethereumjs-verkle-0.0.2.tgz", + "integrity": "sha512-bjnfZElpYGK/XuuVRmLS3yDvr+cDs85D9oonZ0YUa5A3lgFgokWMp76zXrxX2jVQ0BfHaw12y860n1+iOi6yFQ==", + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "lru-cache": "^10.0.0", + "rust-verkle-wasm": "^0.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.4.tgz", + "integrity": "sha512-gsA4IhmtWHI4BofKy3kio9W+dqZQs5Ji5mLjLYxHCkat+JQBUt5szjRKra2F9nGDJ2XcI/wWb0YWUFNgln4zRQ==", + "dependencies": { + "@nomicfoundation/ethereumjs-block": "5.0.4", + "@nomicfoundation/ethereumjs-blockchain": "7.0.4", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-evm": "2.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-statemanager": "2.0.4", + "@nomicfoundation/ethereumjs-trie": "6.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz", + "integrity": "sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "chai": "^4.2.0", + "ethers": "^6.1.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz", + "integrity": "sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.1.0", + "hardhat": "^2.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz", + "integrity": "sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ==", + "dev": true, + "peer": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.9.5" + } + }, + "node_modules/@nomicfoundation/hardhat-toolbox": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-3.0.0.tgz", + "integrity": "sha512-MsteDXd0UagMksqm9KvcFG6gNKYNa3GGNCy73iQ6bEasEgg2v8Qjl6XA5hjs8o5UD5A3153B6W2BIVJ8SxYUtA==", + "dev": true, + "peerDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-verify": "^1.0.0", + "@typechain/ethers-v6": "^0.4.0", + "@typechain/hardhat": "^8.0.0", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=12.0.0", + "chai": "^4.2.0", + "ethers": "^6.4.0", + "hardhat": "^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typechain": "^8.2.0", + "typescript": ">=4.5.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz", + "integrity": "sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", + "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", + "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", + "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", + "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", + "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", + "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", + "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", + "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", + "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", + "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", + "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==" + }, + "node_modules/@openzeppelin/merkle-tree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/merkle-tree/-/merkle-tree-1.0.6.tgz", + "integrity": "sha512-cGWOb2WBWbJhqvupzxjnKAwGLxxAEYPg51sk76yZ5nVe5D03mw7Vx5yo8llaIEqYhP5O39M8QlrNWclgLfKVrA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "ethereum-cryptography": "^1.1.2" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "dev": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dev": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "dev": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "dev": true + }, + "node_modules/@scure/base": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "peer": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, + "node_modules/@typechain/ethers-v6": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.4.3.tgz", + "integrity": "sha512-TrxBsyb4ryhaY9keP6RzhFCviWYApcLCIRMPyWaKp2cZZrfaM3QBoxXTnw/eO4+DAY3l+8O0brNW0WgeQeOiDA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "ethers": "6.x", + "typechain": "^8.3.1", + "typescript": ">=4.7.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-8.0.3.tgz", + "integrity": "sha512-MytSmJJn+gs7Mqrpt/gWkTCOpOQ6ZDfRrRT2gtZL0rfGe4QrU4x9ZdW15fFbVM/XTa+5EsKiOMYXhRABibNeng==", + "dev": true, + "peer": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "@typechain/ethers-v6": "^0.4.3", + "ethers": "^6.1.0", + "hardhat": "^2.9.9", + "typechain": "^8.3.1" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", + "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", + "dev": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/inquirer": { + "version": "8.2.10", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.2.10.tgz", + "integrity": "sha512-IdD5NmHyVjWM8SHWo/kPBgtzXatwPkfwzyP3fN1jF2g9BWt5WO+8hL2F4o2GKIYsU40PpqeevuUWvkS/roXJkA==", + "dev": true, + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "dev": true + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "peer": true + }, + "node_modules/@types/mocha": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", + "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", + "dev": true + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "18.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.21.tgz", + "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "peer": true + }, + "node_modules/@types/qs": { + "version": "6.9.12", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==", + "dev": true, + "peer": true + }, + "node_modules/@types/readable-stream": { + "version": "2.3.15", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", + "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/through": { + "version": "0.0.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.26", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@wagmi/cli": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@wagmi/cli/-/cli-2.1.4.tgz", + "integrity": "sha512-vamvEo/GeBjFxb5oZCvby4YZDOrK/RqD+tcWb5X0pqmJDyWbN2Mkv9DYTtVB+OtfVUzFKciN/8Vhw8luMtOJbw==", + "dev": true, + "dependencies": { + "abitype": "^0.9.8", + "bundle-require": "^4.0.2", + "cac": "^6.7.14", + "change-case": "^4.1.2", + "chokidar": "^3.5.3", + "dedent": "^0.7.0", + "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", + "esbuild": "^0.19.0", + "execa": "^8.0.1", + "find-up": "^6.3.0", + "fs-extra": "^11.1.1", + "globby": "^13.2.2", + "ora": "^6.3.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "prettier": "^3.0.3", + "viem": "2.*", + "zod": "^3.22.2" + }, + "bin": { + "wagmi": "dist/esm/cli.js" + }, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@wagmi/cli/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@wagmi/cli/node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@wagmi/cli/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wagmi/cli/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "peer": true + }, + "node_modules/abitype": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.9.10.tgz", + "integrity": "sha512-FIS7U4n7qwAT58KibwYig5iFG4K61rbhAqaQh/UWj8v1Y8mjX3F8TC9gd8cz9yT1TYel9f8nS5NO5kZp2RW0jQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wagmi-dev" + } + ], + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/abstract-level": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "peer": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "peer": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "peer": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/bigint-crypto-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", + "integrity": "sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/bs58check/node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58check/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/bundle-require": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz", + "integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==", + "dev": true, + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/case": { + "version": "1.6.3", + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "peer": true + }, + "node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "peer": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "peer": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 5" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "peer": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true, + "peer": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "peer": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "peer": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ds-test": { + "version": "1.0.0", + "resolved": "git+ssh://git@github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0", + "license": "GPL-3.0" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "peer": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "dependencies": { + "@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": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "peer": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dev": true, + "peer": true, + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/ethereumjs-abi/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.11.1.tgz", + "integrity": "sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers-v5": { + "name": "ethers", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.1.tgz", + "integrity": "sha512-5krze4dRLITX7FpU8J4WscXqADiKmyeNlylmmDLbS95DaZpBhDe2YSwRQwKXWNyXcox7a3gBgm/MkGXV1O1S/Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.1", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "peer": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/firebase": { + "version": "9.9.4", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.9.4.tgz", + "integrity": "sha512-XRfCw54nNGYUYNYi5PLJ6rcERN2M+aS32f6caYEx9GhCp9ndgHHzBL9BpPohUpEpKPtHA75EqYNf8kuR0HQndA==", + "dev": true, + "dependencies": { + "@firebase/analytics": "0.8.0", + "@firebase/analytics-compat": "0.1.13", + "@firebase/app": "0.7.32", + "@firebase/app-check": "0.5.12", + "@firebase/app-check-compat": "0.2.12", + "@firebase/app-compat": "0.1.33", + "@firebase/app-types": "0.7.0", + "@firebase/auth": "0.20.6", + "@firebase/auth-compat": "0.2.19", + "@firebase/database": "0.13.6", + "@firebase/database-compat": "0.2.6", + "@firebase/firestore": "3.4.15", + "@firebase/firestore-compat": "0.1.24", + "@firebase/functions": "0.8.4", + "@firebase/functions-compat": "0.2.4", + "@firebase/installations": "0.5.12", + "@firebase/installations-compat": "0.1.12", + "@firebase/messaging": "0.9.16", + "@firebase/messaging-compat": "0.1.16", + "@firebase/performance": "0.5.12", + "@firebase/performance-compat": "0.1.12", + "@firebase/remote-config": "0.3.11", + "@firebase/remote-config-compat": "0.1.12", + "@firebase/storage": "0.9.9", + "@firebase/storage-compat": "0.1.17", + "@firebase/util": "1.6.3" + } + }, + "node_modules/firebase/node_modules/@firebase/app-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==", + "dev": true + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forge-std": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/forge-std/-/forge-std-1.1.2.tgz", + "integrity": "sha512-Wfb0iAS9PcfjMKtGpWQw9mXzJxrWD62kJCUqqLcyuI0+VRtJ3j20XembjF3kS20qELYdXft1vD/SPFVWVKMFOw==" + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "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/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/globby/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globby/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hardhat": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.20.1.tgz", + "integrity": "sha512-q75xDQiQtCZcTMBwjTovrXEU5ECr49baxr4/OBkIu/ULTPzlB20yk1dRWNmD2IFbAeAeXggaWvQAdpiScaHtPw==", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "5.0.4", + "@nomicfoundation/ethereumjs-blockchain": "7.0.4", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-evm": "2.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-statemanager": "2.0.4", + "@nomicfoundation/ethereumjs-trie": "6.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/ethereumjs-verkle": "0.0.2", + "@nomicfoundation/ethereumjs-vm": "7.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-contract-sizer": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.10.0.tgz", + "integrity": "sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0", + "strip-ansi": "^6.0.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/hardhat-contract-sizer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-contract-sizer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-ethernal": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/hardhat-ethernal/-/hardhat-ethernal-3.2.5.tgz", + "integrity": "sha512-Y2PVkd1GN5rZ1bRh26vafsaVOFgHQraSxxp9QEntjufwcCb7NzabKmhBtdWOK6GhNZ+NI78YzVBoAAHlqDPzxw==", + "dev": true, + "dependencies": { + "@firebase/firestore-types": "2.2.0", + "axios": "^0.27.2", + "firebase": "9.9.4" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "hardhat": "^2.17.1" + } + }, + "node_modules/hardhat-ethernal/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "peer": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat-tracer": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-2.8.1.tgz", + "integrity": "sha512-wCTxv/ZY/Nw7sdbCKlnVmywVPRIjWH6jZKX+l1G4nhKjAqqkeHUvDVNlBuEA+LKuRJmEnEmxk3g9PKDDAbxrMw==", + "dependencies": { + "chalk": "^4.1.2", + "debug": "^4.3.4", + "ethers": "^5.6.1" + }, + "peerDependencies": { + "chai": "4.x", + "hardhat": ">=2.16 <2.21.0" + } + }, + "node_modules/hardhat-tracer/node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/hardhat-tracer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-tracer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-tracer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-tracer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/hardhat-tracer/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/hardhat-tracer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-tracer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-tracer/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/hardhat/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/hardhat/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/hardhat/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/hardhat/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/hardhat/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "peer": true + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "peer": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "peer": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==", + "dev": true + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, + "node_modules/immutable": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": true + }, + "node_modules/inquirer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.0.1.tgz", + "integrity": "sha512-BwZ5KPT4cY1Hg6nzhFA0NBx4ae8n1T4zCD0vr1qQMo8EsO+bLLtwfwSyhi7E1i+Dcpi8UNuCQYC7H8QpvOFZzg==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.6", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isows": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz", + "integrity": "sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wagmi-dev" + } + ], + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-sdsl": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "peer": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true, + "peer": true + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "8.1.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multiformats": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "peer": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "peer": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.3.1.tgz", + "integrity": "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==", + "dev": true, + "dependencies": { + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true, + "peer": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true, + "peer": true + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.3.1.tgz", + "integrity": "sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.17.0", + "semver": "^7.5.4", + "solidity-comments-extractor": "^0.0.8" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "prettier": ">=2.3.0" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.17.0.tgz", + "integrity": "sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw==", + "dev": true + }, + "node_modules/prettier-plugin-solidity/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "peer": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "peer": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "peer": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rust-verkle-wasm": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/rust-verkle-wasm/-/rust-verkle-wasm-0.0.1.tgz", + "integrity": "sha512-BN6fiTsxcd2dCECz/cHtGTt9cdLJR925nh7iAuRcj8ymKw7OOaPmCneQZ7JePOJ/ia27TjEL91VdOi88Yf+mcA==" + }, + "node_modules/rustbn-wasm": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn-wasm/-/rustbn-wasm-0.2.0.tgz", + "integrity": "sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg==", + "dependencies": { + "@scure/base": "^1.1.1" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "peer": true, + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "dev": true, + "peer": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "peer": true + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sc-istanbul/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/selenium-webdriver": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.1.2.tgz", + "integrity": "sha512-e4Ap8vQvhipgBB8Ry9zBiKGkU6kHKyNnWiavGGLKkrdW81Zv7NVMtFOL/j3yX0G8QScM7XIXijKssNd4EUxSOw==", + "dev": true, + "dependencies": { + "jszip": "^3.6.0", + "tmp": "^0.2.1", + "ws": ">=7.4.6" + }, + "engines": { + "node": ">= 10.15.0" + } + }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "peer": true, + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "peer": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-git": { + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.24.0.tgz", + "integrity": "sha512-QqAKee9Twv+3k8IFOFfPB2hnk6as6Y6ACUpwCtQvRYBAes23Wv3SZlHVobAzqcE8gfsisCvPw3HGW3HYM+VYYw==", + "dev": true, + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-bytes-utils": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/solidity-bytes-utils/-/solidity-bytes-utils-0.8.2.tgz", + "integrity": "sha512-cqXPYAV2auhpdKSTPuqji0CwpSceZDu95CzqSM/9tDJ2MoMaMsdHTpOIWtVw31BIqqGPNmIChCswzbw0tHaMTw==", + "dependencies": { + "ds-test": "github:dapphub/ds-test", + "forge-std": "^1.1.2" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.8.tgz", + "integrity": "sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g==", + "dev": true + }, + "node_modules/solidity-coverage": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.10.tgz", + "integrity": "sha512-6nvlWLnCjBIVnCgTZiIo2XBI62O3YJuU83xj+bklnH/B+dXGTjuQB7SccZfysUC3LFkjtZO/KjzUJ/hiSlkXWw==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.18.0", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true, + "peer": true + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solidity-coverage/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solidity-coverage/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "dev": true, + "dependencies": { + "bl": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "dev": true, + "peer": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "peer": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + }, + "bin": { + "write-markdown": "dist/write-markdown.js" + } + }, + "node_modules/ts-command-line-args/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-command-line-args/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/ts-command-line-args/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-command-line-args/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" + } + }, + "node_modules/typechain/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/typechain/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typechain/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/typechain/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typechain/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "peer": true + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "dependencies": { + "multiformats": "^9.4.2" + } + }, + "node_modules/undici": { + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true + }, + "node_modules/viem": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.9.2.tgz", + "integrity": "sha512-GRakUTNiYE9W+vL+Be9JkQfzWnkczerHtSpEe2JR/jEGTYZAs4shrA4WLgiaVCI9JxpnduZhQfRWNvy2dlyP2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.0", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@scure/bip32": "1.3.2", + "@scure/bip39": "1.2.1", + "abitype": "1.0.0", + "isows": "1.0.3", + "ws": "8.13.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@adraffy/ens-normalize": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", + "dev": true + }, + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.2.tgz", + "integrity": "sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==", + "dev": true, + "dependencies": { + "@noble/curves": "~1.2.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dev": true, + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/abitype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz", + "integrity": "sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", + "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", + "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", + "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.3.0", + "@noble/hashes": "1.3.3", + "@scure/bip32": "1.3.3", + "@scure/bip39": "1.2.2" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "peer": true + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "peer": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json index e087a9f..95a7cae 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,53 @@ { - "name": "LitNodeContracts", + "name": "lit-assets-blockchain", "version": "1.0.0", "main": "index.js", "license": "GPL-3.0-or-later", "scripts": { - "test": "npx hardhat test | tee gas_costs.txt", + "test": "npx hardhat test --network localchain | tee gas_costs.txt; npx hardhat size-contracts | tee -a gas_costs.txt", + "test:ci": "LIT_SLOW_DOWN_PROVIDER=true npx hardhat test --network localchain", "compile": "npx hardhat compile", "convertPubkey": "node pubkeyToRoutingData.js", "convertIpfsId": "node ipfsIdToParts.js", "hashIpfsId": "node ipfsIdToHash.js", - "prettier": "prettier -c -w '**/*.js' '**/*.sol' '**/*.md'" + "prettier:check": "npx prettier --config .prettierrc.json --check .", + "prettier:write": "npx prettier --config .prettierrc.json --write .", + "deploy": "npx ts-node scripts/deploy.ts" }, "devDependencies": { - "@defi-wonderland/smock": "^2.1.0", - "@nomiclabs/hardhat-ethers": "^2.0.0", - "@nomiclabs/hardhat-etherscan": "^3.1.7", - "@nomiclabs/hardhat-waffle": "^2.0.0", + "@nomicfoundation/hardhat-toolbox": "^3.0.0", "@openzeppelin/merkle-tree": "^1.0.1", - "chai": "^4.2.0", - "ethereum-waffle": "^3.0.0", - "hardhat": "^2.12.0", - "hardhat-gas-reporter": "^1.0.9", + "@types/chai": "^4.3.4", + "@types/inquirer": "^8.1.0", + "@types/mocha": "^10.0.1", + "@types/node": "^18.15.11", + "@types/yargs": "^17.0.24", + "@wagmi/cli": "^2.1.4", + "glob": "^10.2.1", + "hardhat": "^2.20.1", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-ethernal": "^3.2.0", "prettier": "^2.7.1", - "prettier-plugin-solidity": "^1.0.0-beta.19" + "prettier-plugin-solidity": "^1.1.3", + "simple-git": "^3.24.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.4", + "yargs": "^17.7.1" }, "dependencies": { + "@gnus.ai/contracts-upgradeable-diamond": "GeniusVentures/openzeppelin-contracts-diamond", + "@iarna/toml": "^2.2.5", + "@kingdomstudios/hardhat-diamond-abi": "^2.2.0", "@noble/ed25519": "^1.7.1", - "@openzeppelin/contracts": "^4.7.0", - "@tenderly/hardhat-tenderly": "^1.1.6", + "@openzeppelin/contracts": "^4.9.6", + "axios": "^1.6.2", "bs58": "^5.0.0", - "dotenv": "^16.0.3", - "ethers": "^5.7.1", - "solidity-bytes-utils": "^0.8.0", + "dotenv": "^16.4.5", + "ethers": "^6.1.0", + "ethers-v5": "npm:ethers@5.7.1", + "hardhat-tracer": "^2.8.1", + "inquirer": "8.0.1", + "solidity-bytes-utils": "^0.8.2", "tweetnacl": "^1.0.3", "uint8arrays": "3", "uuid": "^8.3.2" diff --git a/pubkeyToRoutingData.js b/pubkeyToRoutingData.js deleted file mode 100644 index 29a28d6..0000000 --- a/pubkeyToRoutingData.js +++ /dev/null @@ -1,20 +0,0 @@ -const ethers = require("ethers"); - -const pubkey = - "0x0381bb0e93a94063d92fc4e5e22e91fc7ffa9335ae35c16d69341d1a35596594c9"; - -const keyPart1Bytes = ethers.utils.hexDataSlice(pubkey, 0, 32); -const keyPart2Bytes = ethers.utils.hexZeroPad( - ethers.utils.hexDataSlice(pubkey, 32), - 32 -); -const keyLength = pubkey.replace(/^0x/, "").length / 2; -const keyType = 2; - -const tokenId = ethers.utils.keccak256(pubkey); - -console.log("tokenId", tokenId); -console.log("keyPart1Bytes", keyPart1Bytes); -console.log("keyPart2Bytes", keyPart2Bytes); -console.log("keyLength", keyLength); -console.log("keyType", keyType); diff --git a/runHardhatScript.sh b/runHardhatScript.sh deleted file mode 100755 index dc6e0cd..0000000 --- a/runHardhatScript.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -npx hardhat run --network mumbai scripts/$1 \ No newline at end of file diff --git a/scripts/add_to_allowlist.js b/scripts/add_to_allowlist.js index 82ee8e9..41a4ac4 100644 --- a/scripts/add_to_allowlist.js +++ b/scripts/add_to_allowlist.js @@ -1,57 +1,57 @@ /* This file is not completed yet, since the private key for the allowlist admin * lives in metamask. This is probably almost working though */ -const hre = require("hardhat"); -const fs = require("fs"); -var spawn = require("child_process").spawn; -const { getBytesFromMultihash } = require("./utils.js"); +const hre = require('hardhat'); +const fs = require('fs'); +var spawn = require('child_process').spawn; +const { getBytesFromMultihash } = require('../utils'); const { ethers } = hre; const chainName = hre.network.name; const rpcUrl = hre.network.config.url; async function getChainId() { - const { chainId } = await ethers.provider.getNetwork(); - return chainId; + const { chainId } = await ethers.provider.getNetwork(); + return chainId; } const getSigner = async () => { - const [deployer] = await ethers.getSigners(); - return deployer; + const [deployer] = await ethers.getSigners(); + return deployer; }; async function main() { - const signer = await getSigner(); + const signer = await getSigner(); - const rl = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, - }); + const rl = require('readline').createInterface({ + input: process.stdin, + output: process.stdout, + }); - const allowlistContractAddress = await new Promise((resolve) => { - rl.question("What is the Allowlist contract address? ", resolve); - }); + const allowlistContractAddress = await new Promise((resolve) => { + rl.question('What is the Allowlist contract address? ', resolve); + }); - let ipfsId = await new Promise((resolve) => { - rl.question("What is the IPFS CID? ", resolve); - }); + let ipfsId = await new Promise((resolve) => { + rl.question('What is the IPFS CID? ', resolve); + }); - // convert the ipfsId to bytes - const ipfsIdBytes = getBytesFromMultihash(ipfsId); + // convert the ipfsId to bytes + const ipfsIdBytes = getBytesFromMultihash(ipfsId); - const allowlistContract = await ethers.getContractAt( - "Allowlist", - allowlistContractAddress, - signer - ); + const allowlistContract = await ethers.getContractAt( + 'Allowlist', + allowlistContractAddress, + signer + ); - const addTx = await allowlistContract.setAllowed(ipfsIdBytes); - console.log("Success!"); - process.exit(0); + const addTx = await allowlistContract.setAllowed(ipfsIdBytes); + console.log('Success!'); + process.exit(0); } // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main().catch((error) => { - console.error(error); - process.exitCode = 1; + console.error(error); + process.exitCode = 1; }); diff --git a/scripts/admin/changeOwners.js b/scripts/admin/changeOwners.js new file mode 100644 index 0000000..9e37138 --- /dev/null +++ b/scripts/admin/changeOwners.js @@ -0,0 +1,333 @@ +const { hre } = require('hardhat'); +const fs = require('fs'); + +/* contracts we aren't changing: + * - DomainWalletRegistryAddress - changing to diamond, not used in current deployment anyway + * - DomainWalletOracleAddress- changing to diamond, not used in current deployment anyway + * - hdKeyDeriver - no Owner + * - LitToken - Not used in current deployment, littoken is native gas on chronicle + * - PKPNFTMetadata - no owner + */ + +// put your new owner here. YOU MUST HAVE THE ABILITY TO SEND TXNS FROM HERE OR ELSE YOU COULD END UP SETTING AN OWNER THAT YOU CAN'T EVER CHANGE +const NEW_OWNER = '0x6D3f1E51D550a343714c12a9E4ecc4a441CD0484'; + +const LIT_CORE_ADDRESSES_PATH = + '../../../networks/habanero/deployed-lit-core-contracts-temp.json'; +const LIT_NODE_ADDRESSES_PATH = + '../../../networks/habanero/deployed-lit-node-contracts-temp.json'; + +// const LIT_CORE_ADDRESSES_PATH = "./deployed-lit-core-contracts-temp.json"; +// const LIT_NODE_ADDRESSES_PATH = "./deployed-lit-node-contracts-temp.json"; + +// let's not change the lit core admin for now +// const LIT_CORE_ADMIN_PK = process.env.LIT_CORE_ADMIN_PK; + +const CONTRACTS = { + BackupRecovery: { + name: 'BackupRecovery', + ownerType: 'diamond', + project: 'node', + addressKey: 'backupRecoveryContractAddress', + }, + Staking: { + name: 'Staking', + ownerType: 'diamond', + project: 'node', + addressKey: 'stakingContractAddress', + }, + StakingBalances: { + name: 'StakingBalances', + ownerType: 'diamond', + project: 'node', + addressKey: 'stakingBalancesContractAddress', + }, + PubkeyRouter: { + name: 'PubkeyRouter', + ownerType: 'diamond', + project: 'node', + addressKey: 'pubkeyRouterContractAddress', + }, + PKPNFT: { + name: 'PKPNFT', + ownerType: 'diamond', + project: 'node', + addressKey: 'pkpNftContractAddress', + }, + RateLimitNFT: { + name: 'RateLimitNFT', + ownerType: 'diamond', + project: 'node', + addressKey: 'rateLimitNftContractAddress', + }, + PKPPermissions: { + name: 'PKPPermissions', + ownerType: 'diamond', + project: 'node', + addressKey: 'pkpPermissionsContractAddress', + }, + Allowlist: { + name: 'Allowlist', + ownerType: 'ownable', + project: 'node', + addressKey: 'allowlistContractAddress', + }, + PKPHelper: { + name: 'PKPHelper', + ownerType: 'ownable', + project: 'node', + addressKey: 'pkpHelperContractAddress', + }, + // this contract has no owner + // "PKPNFTMetadata": { + // name: "PKPNFTMetadata", + // ownerType: "roles", + // project: "node", + // addressKey: "pkpNftMetadataContractAddress" + // }, + ContractResolver: { + name: 'ContractResolver', + ownerType: 'roles', + project: 'core', + addressKey: 'contractResolver', + probableAdmin: '0x046BF7BB88E0e0941358CE3F5A765C9acddA7B9c', + }, + // let's not change this right now + // ReleaseRegister: { + // name: "ReleaseRegister", + // ownerType: "roles", + // project: "core", + // addressKey: "releaseRegisterContractAddress", + // probableAdmin: "0xB77AEBbC262Bb809933D991A919A0e4A6A3b2f65", + // }, +}; + +const ADMIN_ROLE = ethers.keccak256(ethers.toUtf8Bytes('ADMIN')); + +// function getDiamondAbi(contractName) { +// const abiPath = `./abis/${contractName}.abi`; +// const abi = JSON.parse(fs.readFileSync(abiPath)); +// return abi; +// } + +// // uses the default hardhat wallet to set new owners +// async function addNewOwner(contractResolverAddress) { +// const resolver = await ethers.getContractAt("ContractResolver", contractResolverAddress); + +// //contract = new Contract("dai.tokens.ethers.eth", abi, provider) +// } + +async function changeOwners(contracts, addresses) { + const previousOwner = (await ethers.getSigners())[0]; + console.log('previousOwner', previousOwner.address); + if (NEW_OWNER.toLowerCase() === previousOwner.address.toLowerCase()) { + throw new Error( + 'You are already the owner. Running this script with the same owner will break the role-based contracts' + ); + } + for (contractName of Object.keys(contracts)) { + const contractInfo = contracts[contractName]; + const contractAddress = addresses[contractInfo.addressKey]; + await changeOwner({ ...contractInfo, address: contractAddress }); + } +} + +async function changeOwner(contractInfo) { + console.log(`changeOwner with ${JSON.stringify(contractInfo, null, 2)}`); + if (contractInfo.ownerType === 'diamond') { + return changeDiamondOwner(contractInfo); + } else if (contractInfo.ownerType === 'ownable') { + return changeOwnableOwner(contractInfo); + } else if (contractInfo.ownerType === 'roles') { + return changeRoleAdmin(contractInfo); + } else { + throw new Error(`Invalid ownerType for contract ${contractInfo.name}`); + } +} + +async function changeDiamondOwner(contractInfo) { + const contract = await ethers.getContractAt( + 'OwnershipFacet', + contractInfo.address + ); + const tx = await contract.transferOwnership(NEW_OWNER); + console.log( + `Transferring ownership of ${contractInfo.name} to ${NEW_OWNER} with tx hash ${tx.hash}` + ); + await tx.wait(); + console.log(`Ownership of ${contractInfo.name} transferred to ${NEW_OWNER}`); +} + +async function changeOwnableOwner(contractInfo) { + const contract = await ethers.getContractAt( + contractInfo.name, + contractInfo.address + ); + const tx = await contract.transferOwnership(NEW_OWNER); + console.log( + `Transferring ownership of ${contractInfo.name} to ${NEW_OWNER} with tx hash ${tx.hash}` + ); + await tx.wait(); + console.log(`Ownership of ${contractInfo.name} transferred to ${NEW_OWNER}`); +} + +async function changeRoleAdmin(contractInfo) { + if (contractInfo.project !== 'core') { + throw new Error( + `Only core contracts can be changed with the changeRoleAdmin function. ${contractInfo.name} is not a core contract` + ); + } + // const litCoreAdminWallet = new ethers.Wallet( + // LIT_CORE_ADMIN_PK, + // ethers.provider + // ); + const hardhartAdminWallet = (await ethers.getSigners())[0]; + + let previousOwner = hardhartAdminWallet; + // if (contractInfo.owner === litCoreAdminWallet.address) { + // previousOwner = litCoreAdminWallet; + // } else if (contractInfo.owner === hardhartAdminWallet.address) { + // previousOwner = hardhartAdminWallet; + // } else { + // throw new Error( + // `Could not find private key for owner for ${contractInfo.name}. Owner address is ${contractInfo.owner}` + // ); + // } + + if (previousOwner.address.toLowerCase() === NEW_OWNER.toLowerCase()) { + throw new Error( + `${NEW_OWNER} is already the owner. Running this script with the same owner will break the role-based contracts` + ); + } + + const contract = ( + await ethers.getContractAt(contractInfo.name, contractInfo.address) + ).connect(previousOwner); + const tx = await contract.grantRole(ADMIN_ROLE, NEW_OWNER); + console.log( + `Transferring admin role of ${contractInfo.name} to ${NEW_OWNER} with tx hash ${tx.hash}` + ); + await tx.wait(); + console.log(`Admin role of ${contractInfo.name} transferred to ${NEW_OWNER}`); + const renounceTx = await contract.renounceRole( + ADMIN_ROLE, + previousOwner.address + ); + console.log( + `Renouncing admin role of ${contractInfo.name} from ${previousOwner.address} with tx hash ${renounceTx.hash}` + ); + await renounceTx.wait(); + console.log( + `Admin role of ${contractInfo.name} renounced by ${previousOwner.address}` + ); +} + +async function getOwners(contracts, addresses) { + const owners = {}; + for (contractName of Object.keys(contracts)) { + const contractInfo = contracts[contractName]; + const contractAddress = addresses[contractInfo.addressKey]; + const owner = await getOwner({ + ...contractInfo, + address: contractAddress, + }); + owners[contractName] = { ...contractInfo, owner }; + } + return owners; +} + +function getOwner(contract) { + if (contract.ownerType === 'diamond') { + return getDiamondOwner(contract); + } else if (contract.ownerType === 'ownable') { + return getOwnableOwner(contract); + } else if (contract.ownerType === 'roles') { + return getRoleAdmin(contract); + } else { + throw new Error(`Invalid ownerType for contract ${contract.name}`); + } +} + +async function getDiamondOwner(contractInfo) { + const contract = await ethers.getContractAt( + 'OwnershipFacet', + contractInfo.address + ); + const owner = await contract.owner(); + return owner; +} + +async function getOwnableOwner(contractInfo) { + const contract = await ethers.getContractAt( + contractInfo.name, + contractInfo.address + ); + const owner = await contract.owner(); + return owner; +} + +async function getRoleAdmin(contractInfo) { + const contract = await ethers.getContractAt( + contractInfo.name, + contractInfo.address + ); + const hasRole = await contract.hasRole( + ADMIN_ROLE, + contractInfo.probableAdmin + ); + if (hasRole) { + return contractInfo.probableAdmin; + } + throw new Error(`Could not determine owner for ${contractInfo.name}`); +} + +const go = async () => { + // saved for later - we don't need to change the core admin right now + // if (!LIT_CORE_ADMIN_PK || LIT_CORE_ADMIN_PK == "") { + // throw new Error("LIT_CORE_ADMIN_PK environment variable is not set."); + // } + + const nodeAddresses = JSON.parse(fs.readFileSync(LIT_NODE_ADDRESSES_PATH)); + const coreAddresses = JSON.parse(fs.readFileSync(LIT_CORE_ADDRESSES_PATH)); + const addresses = { + ...nodeAddresses, + ...coreAddresses, + }; + // check ownership of contracts + const contractsWithOwners = await getOwners(CONTRACTS, addresses); + console.log( + `Owners before change: ${JSON.stringify(contractsWithOwners, null, 2)}` + ); + + await changeOwners(contractsWithOwners, addresses); + console.log('Owners changed'); + + const contractsWithNewProbableOwners = { ...CONTRACTS }; + for (contractName of Object.keys(contractsWithNewProbableOwners)) { + const contractInfo = contractsWithNewProbableOwners[contractName]; + if (contractInfo.project === 'core') { + contractsWithNewProbableOwners[contractName].probableAdmin = NEW_OWNER; + } + } + + const newOwners = await getOwners(contractsWithNewProbableOwners, addresses); + console.log(`Owners after change: ${JSON.stringify(newOwners, null, 2)}`); + + for (contractName of Object.keys(newOwners)) { + const contractInfo = newOwners[contractName]; + if (contractInfo.owner.toLowerCase() !== NEW_OWNER.toLowerCase()) { + throw new Error( + `Ownership of ${contractInfo.name} was not transferred to ${NEW_OWNER}` + ); + } + } +}; + +if (require.main === module) { + go() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); +} diff --git a/scripts/commsKeyPrivateToPublic.js b/scripts/commsKeyPrivateToPublic.js index 695db85..de2c771 100644 --- a/scripts/commsKeyPrivateToPublic.js +++ b/scripts/commsKeyPrivateToPublic.js @@ -1,33 +1,31 @@ -const nacl = require("tweetnacl"); -const { fromString } = require("uint8arrays/from-string"); -const { toString } = require("uint8arrays/to-string"); +const nacl = require('tweetnacl'); +const { fromString } = require('uint8arrays/from-string'); +const { toString } = require('uint8arrays/to-string'); async function main() { - const rl = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, - }); + const rl = require('readline').createInterface({ + input: process.stdin, + output: process.stdout, + }); - const secretKey = await new Promise((resolve) => { - rl.question( - "What is the comms key private key you wish to make into a public key? ", - resolve - ); - }); - - const keys = nacl.box.keyPair.fromSecretKey( - fromString(secretKey, "base16") + const secretKey = await new Promise((resolve) => { + rl.question( + 'What is the comms key private key you wish to make into a public key? ', + resolve ); - console.log("Public key: ", toString(keys.publicKey, "base16")); + }); + + const keys = nacl.box.keyPair.fromSecretKey(fromString(secretKey, 'base16')); + console.log('Public key: ', toString(keys.publicKey, 'base16')); } // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main() - .then(() => { - process.exit(0); - }) - .catch((error) => { - console.error(error); - process.exit(1); - }); + .then(() => { + process.exit(0); + }) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/constants.ts b/scripts/constants.ts new file mode 100644 index 0000000..463b87a --- /dev/null +++ b/scripts/constants.ts @@ -0,0 +1,36 @@ +export const CONTRACT_NAME_TO_JSON_CONTRACT_ADDRESS_KEY = { + Staking: 'stakingContractAddress', + Multisender: 'multisenderContractAddress', + LITToken: 'litTokenContractAddress', + AccessControlConditions: 'accessControlConditionsContractAddress', + PubkeyRouter: 'pubkeyRouterContractAddress', + PKPNFT: 'pkpNftContractAddress', + RateLimitNFT: 'rateLimitNftContractAddress', + PKPHelper: 'pkpHelperContractAddress', + PKPPermissions: 'pkpPermissionsContractAddress', + PKPNFTMetadata: 'pkpNftMetadataContractAddress', + Allowlist: 'allowlistContractAddress', + ContractResolver: 'resolverContractAddress', + DomainWalletRegistry: 'domainWalletRegistryAddress', + KeyDeriver: 'KeyDeriverAddress', + PaymentDelegation: 'paymentDelegationAddress', +}; + +export const CONTRACT_NAME_TO_DIAMOND_ABI_PATH = { + Staking: + '../artifacts/hardhat-diamond-abi/StakingDiamond.sol/StakingDiamond.json', + PKPPermissions: + '../artifacts/hardhat-diamond-abi/PKPPermissionsDiamond.sol/PKPPermissionsDiamond.json', + PubkeyRouter: + '../artifacts/hardhat-diamond-abi/PubkeyRouterDiamond.sol/PubkeyRouterDiamond.json', + RateLimitNFT: + '../artifacts/hardhat-diamond-abi/RateLimitNFTDiamond.sol/RateLimitNFTDiamond.json', + StakingBalances: + '../artifacts/hardhat-diamond-abi/StakingBalancesDiamond.sol/StakingBalancesDiamond.json', + PKPNFT: + '../artifacts/hardhat-diamond-abi/PKPNFTDiamond.sol/PKPNFTDiamond.json', + DomainWalletRegistry: + '../artifacts/hardhat-diamond-abi/DomainWalletRegistryDiamond.sol/DomainWalletRegistryDiamond.json', + PaymentDelegation: + '../artifacts/hardhat-diamond-abi/PaymentDelegationDiamond.sol/PaymentDelegationDiamond.json', +}; diff --git a/scripts/count_all_pkp_mints_from_all_contracts.js b/scripts/count_all_pkp_mints_from_all_contracts.js new file mode 100644 index 0000000..30bfb16 --- /dev/null +++ b/scripts/count_all_pkp_mints_from_all_contracts.js @@ -0,0 +1,167 @@ +// We require the Hardhat Runtime Environment explicitly here. This is optional +// but useful for running the script in a standalone fashion through `node